Creating a new WindowsFormsSynchronizationContext
I have an asynchronous method in a singleton class that needs to fire an event on the UI thread because most people subscribed to the event are controls, but the caller of the method isn't a control. Because the caller isn't a always control I can't pass it in to Invoke on back to the UI thread so instead I'm using AsyncOperation/SynchronizationContext to get the current thread context before starting the background thread, then in the background thread I call Post, kinda like so...
public void AsyncMethod()
{
AsyncOperation ao = AsyncOperationManager.CreateOperation(null);
// or SynchronizationContext ctx = WindowsFormsSynchronizationContext.Current;
ThreadPool.QueueUserWorkItem(delegate(objact state)
{
//do stuff
ao.Post(delegate(object state2)
{
// fire event
}, null);
}, null);
}
The problem is is that AsyncOperation 开发者_StackOverflow社区sometimes gives me a new context, or WindowsFormsSynchronizationContext is null. I found someone else who was having the same problem and I think it relates it relates to drop down menu items creating controls, which would be happening in of the events. Anyways, my question is, if WindowsFormsSynchronizationContext is null, can I create a new one to call Post on, and will that new one be the context of the UI thread, or the context of the thread it was created in?
If this is a singleton in a UI app I would recommend keeping a private member of type Control which was created on the UI thread, and using it for all your invokes:
- You can either require an "initialize" method to be called from a UI thread (say right before Application.Run) and instantiate you sync Control there
- Or you can create the sync Control when your singleton is first accessed, either by checking if the current thread is running a message loop(with Application.MessageLoop) and if not invoking the control creation on one of Application.OpenForms.
The fist way is more deterministic, and thus recommended.
精彩评论