What is SynchronizationContext all about
By | August 20, 2011

While working with UI based applications, one of the most important thing that you need to keep in mind is Thread Affinity. It ensures that every control needs to be created in the UI Thread to be ported in the UI and each of them could only be accessed through UI Thread only. Earlier, the Windows Forms application uses ISynchronizeInvoke interface to invoke a code in its own Thread. SynchronizationContext is a new Threading model which allows you to easily communicate with other Threading models to simplify the Synchronous and asynchronous operation on it.

SynchronizationContext is a new class introduced recently and is been widely used in the .NET base class library itself (in async CTP for instance) provides a new way of implementing the Threading Model for your application. It represents the abstract base class for a model which has two methods namely, Send (which invokes a delegate synchronously) and Post (which invokes a delegate asynchronously). Each of these method takes a delegate of type SendOrPostCallback and the state object. Each time the SynchronizationContext is created, it associates the current Thread to its context, so based on the Thread in which the block is executing, the SynchronizationContext.Current always gets you the object that is created in the Current Thread.

Remember : The Post actually uses ThreadPool internally to call the callback you pass asynchronously.

Now lets create a class that uses SynchronizationContext :

public class MyCallerType
{
    private Thread currentThread;

    private SynchronizationContext context;

    public event EventHandler EventCallback;

    public MyCallerType()
    {
        context = SynchronizationContext.Current;
        context = context ?? new SynchronizationContext();

        currentThread = new Thread(new ThreadStart(Run));
        currentThread.Start();
    }

    private void CallEventHandler(object state)
    {
        EventHandler handler = EventCallback;

        if (handler != null)
        {
            handler(this, EventArgs.Empty);
        }
    }

    private void Run()
    {
        context.Send(new SendOrPostCallback(this.CallEventHandler), null);
    }
    private void RunAsync()
    {
        context.Post(new SendOrPostCallback(this.CallEventHandler), null);
    }
}

The class MyCallerType actually holds the current SynchronizationContext type itself. So when Run or RunAsync is called, it gets the current Thread form its SynchronizationContext (which is held from its object creation) and invokes it.

I hope you enjoyed this post. I will cover bit more later.

Thank you for reading.