Multiple Publish Deadlock #263
-
I am running into a situation where I think the EventAggregator is locking up. The gist of my code is: A service that creates a thread that reads from a serial port 1/s and publishes an event containing the string from the SerialPort read. This event is subscribed to in a viewmodel so that it can update the UI with data coming from the serial port. Another event is published whenever a button is pressed to let the It appears that whenever that button is pressed at the same time the serial port event is being published that the application comes to a deadlock. It looks like the Sample Code: Serial Reader Thread
Button Click in MyViewModel
I am wondering if this is the expected behaviour? I think it should also be noted that even if I removed all the subscribers from the events it still deadlocked. Call Stack:
Thread 5028:
|
Beta Was this translation helpful? Give feedback.
Replies: 2 comments 1 reply
-
Ouch, that's a nice one. Your second thread called into the event aggregator from a non UI thread. That's fine, but it means the handlers are invoked on that same background thread. The handler is invoked while handlersLock is held, and updates a BindableCollection. When a BindableCollection is updated from a non UI thread, it synchronously sends its CollectionChanged event invocation to the UI thread, and waits for it to complete (WPF crashes out if CollectionChanged is invoked on a non UI thread). While that was happening, your first thread called into the event aggregator from the UI thread, and tried to acquire handlersLock. However, that lock is held by the second thread, which is blocked waiting for the UI to fire the CollectionChanged event. So the UI thread is waiting for a lock, and the thing holding for the lock is waiting for the UI thread to fire the CollectionChanged event. And that's your deadlock. Calling PublishOnUIThread is the right approach: you shouldn't be running ViewModel code on background threads, and that means that BindableCollection doesn't have to do expensive synchronous dispatches to the UI thread to fire its CollectionChanged event. That said, the event aggregator shouldn't be calling upwards from within a lock: that's basic best practice. I'll fix that. Nice report, thanks! |
Beta Was this translation helpful? Give feedback.
-
Fixed in #390 |
Beta Was this translation helpful? Give feedback.
Fixed in #390