Como invocar manipulador de eventos dentro de um retorno de chamada assíncrono de tal forma que é executado no segmento de chamada

Eu estou trabalhando em um projeto VS / solução que é usado por diferentes aplicativos. Meu trabalho é refatorar o projeto e alterá-lo de usar o método xxxAsync para usar o BeginInvoke.

Eu cheguei a algo semelhante ao seguinte código:

public class AsyncTestModel {
    private delegate string DoTaskDelegate();

    public static EventHandler<TaskCompletedEventArgs> 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;
        }
    }
}

Eu testei isso em um novo projeto de interface do usuário que criei. O projeto da interface do usuário contém um botão e um controle de rótulo. A interface do usuário tem o seguinte código:

    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;
    }

Depois de executar isso, eu encontrei a exceção cross-thread dizendo que o controle 'label1' está sendo acessado de outro thread além do thread que foi criado.

Existe uma maneira de invocar o manipulador de eventos OnTaskCompleted no mesmo segmento que chama o método BeginInvoke? Eu sei que eu poderia apenas usar o InvokeRequired do formulário e chamar BeginInvoke do formulário como o seguinte:

    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;
    }

Mas a solução acima exigirá que eu pergunte e aplique essa solução à outra equipe de desenvolvimento que manipula aplicativos que usam meu projeto / solução. Esses outros desenvolvedores não devem ser obrigados a saber que os métodos conectados ao manipulador de eventos estão sendo executados a partir de segmentos diferentes.

Desde já, obrigado.

questionAnswers(2)

yourAnswerToTheQuestion