Been doing some brief research into multithreaded C# event handling because I had a suspicion that event handlers would simply be called on whatever开发者_如何学编程 thread invoked an event, which turns out to be true.
Now this strikes me as a really bad idea, because the code that subscribes to an event on an object may not be designed to be multithreaded at all, and the implementation of that object (which should be a black box, no?), if multithreaded behind the scenes (as in my case) can cause the subscriber code to be executed on multiple threads, causing all sorts of weird problems.
So my question is, is it possible to push an event back to the thread that originally subscribed to it, thus avoiding any unexpected concurrency at the subscriber level? Or put more abstractly, can I record the current thread at a point in time, and push an event handler call (or any arbitrary piece of code) onto that thread at a later point in time?
The clincher is this: I'm doing this in a DLL that doesn't reference WinForms or WPF. I know constructs exist in those frameworks to allow for this (and I've used them myself) but I want to do this without having to reference those libraries.
A little background:
My design uses background threads to do work on an object which can result in its properties being changed. I use INotifyPropertyChanged to signal changes to those properties to observers. I use WPF outside of the library to display these objects in interfaces, thus INotifyPropertyChanged is useful because it tells WPF to update the screen when a property has changed on the object that is being displayed.
I'm assuming WPF handles multithreaded change notifications internally, so if I stuck solely to WPF there probably wouldn't be a problem. However, I'd like anybody to be able to subscribe to the change events and not have to worry about them being called on background threads.
You can use the SynchronizationContext
class to run code on a UI thread without referencing WinForms or WPF.
Capture SyncronizationContext.Current
whenever you add a handler, then use the captured instances to call each handler.
精彩评论