Using SynchronizationContexts.

SynchronizationContext is new in .NET 2.0, and I haven't found too much written about it yet.  It is used by classes like BackgroundWorker and some other built-in classes, and I wanted to show how you can use it in your code as well.  I came across this while working on my WinCast project where I needed to handle events coming from the RSS synchronization engine on a background thread.  I wanted to handle these events (like a new feed added) by adding new UI elements.  If you've done any work in Windows programming, you are probably aware that accessing the UI from a thread that didn't create the UI is a big no no.  In .NET 1.1, we could use Invoke on a control to get something executed on the UI thread, but that wasn't the greatest solution.  .NET 2.0 brings us SynchoronizationContext which allows us to execute a section of code in the UI context (the thread that created the UI).  Also, it allows us to specify if the background thread will block waiting for the UI thread (using Send) or will not block (using Post).  You can get the UI context from the WindowsFormsSynchronizationContext.Current property.  Here is an admittedly dumb example of a lastUpdatedTime being updated on a background thread, and the UI being properly updated on the UI thread to show the new time in a textbox.

public partial class UsingContextForm : Form
{
   SynchronizationContext uiContext;
   System.Timers.Timer backgroundTimer;
   DateTime lastUpdated = DateTime.Now;

   public UsingContextForm()
   {
      // save our ui context for use later
      uiContext = WindowsFormsSynchronizationContext.Current;

      InitializeComponent();

      // start a timer on a background thread
      backgroundTimer = new System.Timers.Timer(1000.0);
      backgroundTimer.Elapsed += new System.Timers.ElapsedEventHandler(backgroundTimer_Elapsed);
      backgroundTimer.Start();
   }

   void backgroundTimer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
   {
      //This executes on a background thread
      lastUpdated = DateTime.Now;

      //Tell the ui thread to execute some code for us.
      uiContext.Send(new SendOrPostCallback(
            delegate(object state)
            {
               //This executes on the ui thread
               textBox1.Text = lastUpdated.ToLongTimeString();
            }
         ), null);
   }
}