Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Get SynchronizationContext from a given Thread

I seem not to find how to get the SynchronizationContext of a given Thread:

Thread uiThread = UIConfiguration.UIThread;
SynchronizationContext context = uiThread.Huh?;

Why should I need that?

Because I need to post to the UIThread from different spots all across the front end application. So I defined a static property in a class called UIConfiguration. I set this property in the Program.Main method:

UIConfiguration.UIThread = Thread.CurrentThread;

In that very moment I can be sure I have the right thread, however I cannot set a static property like

UIConfiguration.SynchronizationContext = SynchronizationContext.Current

because the WinForms implementation of that class has not yet been installed. Since each thread has it's own SynchronizationContext, it must be possible to retrieve it from a given Thread object, or am I completely wrong?

like image 999
chiccodoro Avatar asked Nov 05 '10 15:11

chiccodoro


2 Answers

This is not possible. The problem is that a SynchronizationContext and a Thread are really two completely separate concepts.

While it's true that Windows Forms and WPF both setup a SynchronizationContext for the main thread, most other threads do not. For example, none of the threads in the ThreadPool contain their own SynchronizationContext (unless, of course, you install your own).

It's also possible for a SynchronizationContext to be completely unrelated to threads and threading. A synchronization context can easily be setup that synchronizes to an external service, or to an entire thread pool, etc.

In your case, I'd recommend setting your UIConfiguration.SynchronizationContext within the initial, main form's Loaded event. The context is guaranteed to be started at that point, and will be unusable until the message pump has been started in any case.

like image 66
Reed Copsey Avatar answered Oct 20 '22 11:10

Reed Copsey


I know this is an old question, and apologize for the necro, but I just found a solution to this problem that I figured might be useful for those of us who have been googling this (and it doesn't require a Control instance).

Basically, you can create an instance of a WindowsFormsSynchronizationContext and set the context manually in your Main function, like so:

    _UISyncContext = new WindowsFormsSynchronizationContext();
    SynchronizationContext.SetSynchronizationContext(_UISyncContext);

I have done this in my application, and it works perfectly without issues. However, I should point out that my Main is marked with STAThread, so I am not sure if this will still work (or if it's even necessary) if your Main is marked with MTAThread instead.

EDIT: I forgot to mention it, but _UISyncContext is already defined at the module level in the Program class in my application.

like image 23
Javert93 Avatar answered Oct 20 '22 09:10

Javert93