.Net Problem - Async and Windowless Forms

Problem

I was working on a remoting project for an assignment and we came across a problem in 2.0. As of 2.0 you cannot make cross-thread calls to a windows forms control. This means that if you are doing an asyncronous call, most likely, unless your polling the async result, it will come back on a different thread and you cannot change a windows form or the controls on it without coming back to the origonal thread. This is fine if you are making all of your asyncronous calls on the actual form (You just need to call the Invoke method), but if you are seperating the asyncronous logic from the presentation layer (Which is recommended), any results processed from that logic can be difficult to update in windows forms. Fortunatly, there is a solution within the AsyncOperation class. I recommend looking into this class if you are doing anything thread related, but I created a wrapper around the class to make it a bit easier to use. Hopefully, it will be as useful to you as it was for me.

How it works

My wrapper simply operates the AsyncOperation class. When you instantiate the object, you instantiate a copy of the AsyncOperation class which will hold a reference to the initial thread you instantiated it on. This means you can make cross-thread calls to it, and it will execute the code on the origonal thread it was instantiated on. So, if you instantiate this class within your dll’s constructor, any events or code that you execute that need to work on the windows forms thread you just call in an anonymous delegate under the Syncronize method.

Place this class somewhere in your project.

using System;
using System.ComponentModel;
using System.Threading;

/// <summary>
/// Class that allows multithread syncronization
/// from asyncronous calls. Anything wrapped with
/// the syncronize method will be executed on the
/// same thread as where the AsyncSyncronizer
/// is instantiated.
/// </summary>
/// <example>
/// Instantiate on thread you want to use
/// AsyncSyncronizer sync = new AsyncSyncronizer();
///
/// // Run on the code you would like to execute.
/// this.sync.Syncronize(
///        delegate
///        {
///            /*Code to Execute*/
///        });
///</example>
public class AsyncSyncronizer
{
    /// <summary>
    /// Delegate pointing to code executed
    /// within the Syncronize method.
    /// </summary>
    public delegate void AsyncDelegate();
    /// <summary>
    /// Async operation which will push execution
    /// to the proper thread.
    /// </summary>
    private AsyncOperation operation;
    /// <summary>
    /// Creates an object of the AsyncSyncronizer
    /// Everything wrapped within the Syncronize
    /// method will be executed by default on the
    /// thread this is instantiated on. In order to change
    /// the thread, run SetThread.
    /// </summary>
    public AsyncSyncronizer()
    {
        // Set to this thread.
        this.SetThread();
    }
    /// <summary>
    /// Sets the thread code will by syncronized to
    /// to the current thread running.
    /// </summary>
    public void SetThread()
    {
        this.operation =
            AsyncOperationManager.CreateOperation(null);
    }
    /// <summary>
    /// Runs code within this method on the
    /// thread either set by set thread or
    /// where the object was instantiated.
    /// </summary>
    /// <param name=“render”>The code
    /// to execute on the specified thread.</param>
    public void Syncronize(
        AsyncDelegate render)
    {
        this.operation.Post(new SendOrPostCallback(delegate(object state)
        {
            render();
        }), null);
        this.operation.OperationCompleted();
    }
}