James Hirschorn
James Hirschorn

Reputation: 7984

Convert synchronous function to async function in C#

I want to convert a (relatively) slow event handler to async to avoid blocking the other event subscribers. In the example below I do not want the other subscribers to the Message event to have to wait.

The only thing I can think of looks like "cheating":

client.Message += async (object sender, MessageEventArgs e) => {
    await Task.Run(() => { });
    logger.Info("Some info {0}", e.Message);
}

Of course I could wrap the whole logger.Info call in the Task, but I don't see why that is better. I just looks less like cheating.

My only other thought is that the handler should be left synchronous, and the Message event should only be subscribed to when latency is not critical. So I could have a second event that is only used by low latency async subscribers.

I am looking for feedback on the proper coding design here.

Upvotes: 0

Views: 94

Answers (1)

Theodor Zoulias
Theodor Zoulias

Reputation: 43390

You can use Task.Yield if you want to attach an asynchronous handler that will be invoked after all synchronous handlers of the same event have been invoked, and you also want the asynchronous invocation to occur on the current synchronization context. For a GUI application this means that you want the handler to run on the UI thread.

client.Message += async (sender, e) =>
{
    await Task.Yield();
    logger.Info("Some info {0}", e.Message);
}

Don't use await Task.Run(() => { }), because it's just a verbose, idiomatic, less efficient and (possibly) less robust alternative of await Task.Yield().

If you want to attach an asynchronous handler that will run on a ThreadPool thread (instead of the current synchronization context), use Task.Run:

client.Message += async (sender, e) =>
{
    await Task.Run(() => logger.Info("Some info {0}", e.Message));
}

You should only do that if you are sure that the logger object is thread-safe, supports concurrent operations, and doesn't require thread-affinity (like many COM components do).

Upvotes: 1

Related Questions