How to invoke an event asynchronously?

Viewed 5816

I'm building a control that will be used by other developers, and in a few places I have events that the developer can subscribe to do some potentially long operations.

My goal is to give them the option to use async/await, multithreading, backgroundworkers etc. if they choose, but still be able to complete the execution before the event invocation completes. Here's a psuedo-code example (I realize this doesn't compile, but hopefully the intention is clear):

My Code:

public event MyEventHandler MyEvent;
private void InvokeMyEvent()
{
    var args = new MyEventArgs();

    // Keep the UI responsive until this returns
    await MyEvent?.Invoke(this, args);

    // Then show the result
    MessageBox.Show(args.Result);
}

Developer's/subscriber's potential code:

// Option 1: The operation is very quick,
// so the dev doesn't mind doing it synchronously
private void myForm_MyEvent(object sender, MyEventArgs e)
{
    // Short operation, I'll just do it right here.
    string result = DoQuickOperation();
    e.Result = result;
}

// Option 2, The operation is long,
// so the dev wants to do it on another thread and keep the UI responsive.
private void myForm_MyEvent(object sender, MyEventArgs e)
{
    myForm.ShowProgressPanel();

    // Long operation, I want to multithread this!
    Task.Run(() =>
    {
        string result = DoVeryLongOperation();
        e.Result = result;
    })
    .ContinueWith((task) =>
    {
        myForm.HideProgressPanel();
    }
}

Is there any standard way to accomplish this? I was looking at the delegate's BeginInvoke and EndInvoke methods hoping they would help, but I didn't really come up with anything.

Any help or advice would be appreciated! Thanks!

2 Answers
Related