I liked Mike Bouk's answer (+1) so much, I incorporated it into my codebase. I am concerned that his DynamicInvoke call will throw a runtime exception if the Delegate it invokes is not an EventHandler delegate, due to mismatched parameters. And since you're in a background thread, I assume you may want to call the UI method asynchronously and that you are not concerned with whether it ever finishes.
My version below can only be used with EventHandler delegates and will ignore other delegates in its invocation list. Since EventHandler delegates return nothing, we don't need the result. This allows me to call EndInvoke after the asynchronous process completes by passing the EventHandler in the BeginInvoke call. The call will return this EventHandler in IAsyncResult.AsyncState by way of the AsynchronousCallback, at which point EventHandler.EndInvoke is called.
/// <summary>
/// Safely raises any EventHandler event asynchronously.
/// </summary>
/// <param name="sender">The object raising the event (usually this).</param>
/// <param name="e">The EventArgs for this event.</param>
public static void Raise(this MulticastDelegate thisEvent, object sender,
EventArgs e)
{
EventHandler uiMethod;
ISynchronizeInvoke target;
AsyncCallback callback = new AsyncCallback(EndAsynchronousEvent);
foreach (Delegate d in thisEvent.GetInvocationList())
{
uiMethod = d as EventHandler;
if (uiMethod != null)
{
target = d.Target as ISynchronizeInvoke;
if (target != null) target.BeginInvoke(uiMethod, new[] { sender, e });
else uiMethod.BeginInvoke(sender, e, callback, uiMethod);
}
}
}
private static void EndAsynchronousEvent(IAsyncResult result)
{
((EventHandler)result.AsyncState).EndInvoke(result);
}
And the usage:
MyEventHandlerEvent.Raise(this, MyEventArgs);