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.