title: How to invoke event handler inside an asynchronous callback such that is runs in the calling thread
body: <p>I am working on a VS project/solution that is used by different applications.  My job is to refactor the project and change it from using xxxAsync method to using BeginInvoke.</p>
  
  <p>I came up to something similar to the following code:</p>
  
  <pre><code>public class AsyncTestModel {
      private delegate string DoTaskDelegate();
  
      public static EventHandler&lt;TaskCompletedEventArgs&gt; OnTaskCompleted;
  
      public static void InvokeTask() {
          DoTaskDelegate taskDelegate = Task;
          taskDelegate.BeginInvoke(new AsyncCallback(TaskCallback), null);
      }
  
      private static string Task() {
          Thread.Sleep(5000);
          return "Thread Task successfully completed.";
      }
  
      private static void TaskCallback(IAsyncResult ar) {
          string result = ((DoTaskDelegate)((System.Runtime.Remoting.Messaging.AsyncResult)ar).AsyncDelegate).EndInvoke(ar);
          if (OnTaskCompleted != null) {
              OnTaskCompleted(null, new TaskCompletedEventArgs(result));
          }
      }
  }
  
  public class TaskCompletedEventArgs : EventArgs {
      private string _message;
  
      public TaskCompletedEventArgs(string message) : base() {
          _message = message;
      }
  
      public string Message {
          get {
              return _message;
          }
      }
  }
  </code></pre>
  
  <p>I've tested this on a new UI project I've created.  The UI project contains a button and a label controls.  The UI has the following code:</p>
  
  <pre><code>    private void button1_Click(object sender, EventArgs e) {
          AsyncTestModel.OnTaskCompleted += OnTaskCompleted;
          AsyncTestModel.InvokeTask();
      }
  
      private void OnTaskCompleted(object sender, TaskCompletedEventArgs e) {
          UpdateLabel(e.Message);
      }
  
      private void UpdateLabel(string message) {
          this.label1.Text = message;
      }
  </code></pre>
  
  <p>After running this, I've encountered the cross-thread exception saying the the control 'label1' is being accessed from other thread aside the thread that it was created.</p>
  
  <p>Is there a way for me to invoke the OnTaskCompleted event handler on the same thread that calls the BeginInvoke method?  I know I could just use the form's InvokeRequired and call the form's BeginInvoke like the following:</p>
  
  <pre><code>    private delegate void DoUpdateLabelDelegate(string message);
  
      private void UpdateLabel(string message) {
          if (this.InvokeRequired) {
              IAsyncResult ar = this.BeginInvoke(new DoUpdateLabelDelegate(UpdateLabel), message);
              this.EndInvoke(ar);
              return;
          }
          this.label1.Text = message;
      }
  </code></pre>
  
  <p>But the solution above will require me to ask and apply that solution to the other development team handling applications that uses my project/solution.  Those other developers shouldn't be required to know that the methods hooked to the event handler are running from different thread.</p>
  
  <p>Thanks, in advance.</p>