This is a mirror of official site: http://jasper-net.blogspot.com/

Understanding SynchronizationContext

| Wednesday, March 16, 2011
SynchronizationContext - MSDN Lets You Down

I don't know why, but there is really not much information about this new class within the .NET Framework. The MSDN documentation contains very little information on how to use SynchronizationContext. Initially, I must say that I had a hard time understanding the reason for this new class and how to use it. After reading a lot on the subject, I finally understood the purpose of this class and how it should be used. I decided to write this article to help other developers understand how to use this class, and what it can and cannot do for you. (MSDN)

Using SynchronizationContext to Marshal Code from One Thread to Another

Let's get some technical points out of the way so we can show how to use this class. A SynchronizationContext allows a thread to communicate with another thread. Suppose you have two threads, Thread1 and Thread2. Say, Thread1 is doing some work, and then Thread1 wishes to execute code on Thread2. One possible way to do it is to ask Thread2 for its SynchronizationContext object, give it to Thread1, and then Thread1 can call SynchronizationContext.Send to execute the code on Thread2. Sounds like magic... Well, there is a something you should know. Not every thread has a SynchronizationContext attached to it. One thread that always has a SynchronizationContext is the UI thread.

Who puts the SynchronizationContext into the UI thread? Any guesses? Give up? OK, here it is, the first control that is created on the thread places the SynchronizationContext into that thread. Normally, it is the first form that gets created. How do I know? Well, I tried it out.

Because my code uses SynchronizationContext.Current, let me explain what this static property gives us. SynchronizationContext.Current allows us to get a SynchronizationContext that is attached to the current thread. Let's be clear here, SynchronizationContext.Current is not a singleton per AppDomain, but per thread. This means that two threads can have different instances of SynchronizationContext when calling SynchronizationContext.Current. If you wonder where the actual context is stored, it is stored within the Thread data store (and as I said before, not in the global memory space of the appdomain).

OK, let's look at the code that places a SynchronizationContext within our UI thread:

[STAThread]
static void Main()
{
    Application.EnableVisualStyles();
    Application.SetCompatibleTextRenderingDefault(false);

    // let's check the context here
    var context = SynchronizationContext.Current;
    if (context == null)
        MessageBox.Show("No context for this thread");
    else
        MessageBox.Show("We got a context");

    // create a form
    Form1 form = new Form1();

    // let's check it again after creating a form
    context = SynchronizationContext.Current;

    if (context == null)
        MessageBox.Show("No context for this thread");
    else
        MessageBox.Show("We got a context");

    if (context == null)
        MessageBox.Show("No context for this thread");

    Application.Run(new Form1());
}
As you can see, there are a few points to note:

  • The first message box will indicate that there is no context attached to the thread. That's because .NET doesn't even know what is going to happen on this thread, and there is no runtime class that initializes the Sync Context for this thread.
  • Right after creating the form, notice that the context is set. The Form class is responsible for this. It checks if a Sync Context is present, and if it is not, it places it there. Remember that the context is always the same on the same thread, so any UI control can access it. This is because all UI operations must be running on the UI thread. To be more specific, the thread that creates the window is the thread that can communicate with the window. In our case, it is the main thread of the application.

How Do I Use It?

Now that the UI thread is nice enough to give us a Sync Context so we can "run code" under the UI thread, how do we use it?

Read more: Codeproject

Posted via email from Jasper-net

0 comments: