I have a fair amount of windows forms code that uses multiple threads. Because of the way that Windows handles its user interface, you should only be updating the user interface from the main thread. If you try to do it on other threads, bad things happen, and they can be pretty hard to track down.

Windows forms includes some code to detect when that is happening, but it can't do it in all cases. Well, it could, but if it did, the perf would be pretty atrocious.

When you get in this situation, you need to call Invoke() on the form, and pass it a delegate to the function that you want to be called on the main thread. In my case, I need to do an update to my form text when I get an event from the other thread. My code looks something like this:

                // setup code
            object.RemoteUpdate += new UpdateHandler(RemoteUpdateFunc); 
        public void RemoteUpdateFunc2(object sender, RemoteUpdateEventArgs args) 
        { 
            // use the values here. 
        } 
        public void RemoteUpdateFunc(object sender, RemoteUpdateEventArgs args) 
        { 
            this.Invoke(new UpdateHandler(RemoteUpdateFunc2), new object[]
        {sender, args}); 
        }        
   

I have to create a separate function just to do the forwarding, and I have to do that for every event that I want to hook to. That's a lot of boilerplate code that I don't want to write.

So, I set out to try to create a class that could wrap the object. Here's the class that I wrote:

  	public class Invoker
	{
		Delegate d;
		Form form;

		public Invoker(Form form, Delegate d)
		{
			this.d = d;
			this.form = form;
		}

		public Delegate Handler
		{
			get
			{
				return Delegate.CreateDelegate(d.GetType(), this, "Dispatcher");
			}
		}

		public void Dispatcher(object sender, EventArgs args)
		{
			form.Invoke(d, new object[] { sender, args });
		}
	}   

The goal would be to write code like this:

           Invoker invoker = new Invoker(this, new UpdateHandler(RemoteUpdateFunc));
           object.RemoteUpdate += (UpdateHandler) invoker.Handler;
    

Unfortunately, delegates can only point to methods that are *identical* to the delegate definition. You can't, for example use a delegate that's defined as:

        public delegate void EventHandler(object sender, EventArgs args);
    

to point to:

        public delegate void UpdateHandler(object sender, RemoteEventArgs args); 
    

even though RemoteEventArgs is derived from EventArgs. So, that means that you can only use this approach to point to delegates that have EventArgs as their second parameter, which doesn't make it very interesting.

So, I had to abandon this approach. The alternative is to modify the class that I'm using so that it can make the call. I didn't want that class to have to have a reference to the Form class, so I created a delegate like:

        public delegate void InvokeHandler(Delegate d, object[] args);    

and passed that to my the class that has the events. It can then use the delegate to make the Invoke happen. Not as clean as I had hoped, but it does help a bit.