HiveBrain v1.2.0
Get Started
← Back to all entries
patterncsharpMajor

Use of Async/Await for EventHandlers

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
asyncawaiteventhandlersforuse

Problem

I have a MVC WinForms application. I am using Dependency Injection with Ninject as the IoC container.

public class SqlObjectExplorerController : ToolController, ISqlObjectExplorerController
{
    private ISqlObjectExplorerView view = null;
    private SqlServerStructureProvider structureProvider;
    private IProgress progress;

    public SqlObjectExplorerController(ISqlObjectExplorerView view)
    {
        if (view == null)
            throw new ArgumentNullException("view");

        this.view = view;
        InitializeEventHandlers();
        ...
    }

    private void InitializeEventHandlers()
    {
        (view as ToolView).Initialize += new EventHandler(async (s, e) => await RefreshObjectExplorerAsync());
        view.OnRefreshObjectExplorerClicked += new EventHandler(async (s, e) => await RefreshObjectExplorerAsync());
        view.OnAddServerInstanceClicked += new EventHandler(async (s, e) => await AddServerInstanceAsync());
        view.OnNewSqlQueryClicked += new EventHandler((s, e) => OpenNewSqlQueryDocument(e));
        view.OnExpandRequested += new EventHandler((s, e) => BuildSubStructureForDatabaseNode(e));
    }

    private async Task RefreshObjectExplorerAsync()
    {
        await InitializeObjectExplorerAsync();
        view.InitializeObjectExplorer(ServerCache);
    }

    ... // Lots more code.


My question concerns the use of async/await in setting up the likes of += new EventHandler(async (s, e) => await RefreshObjectExplorerAsync());. There are some tasks I need to do on a background thread, so I am using async/await, my questions are about my understanding:

-
In doing async (s, e) => await SomeMethodAsync() I am merely setting up an event handler equivalent to private async void SomeMethodAsync(object s, EventArgs e) { ... }. Which I think is fine in this case of the fire-and-forget Task I want to undertake, is it?

-
I don't think there are any problems in setting this up these async handlers in the ctor of the co

Solution

The things to consider when it comes to async event handlers are:

  • Exceptions thrown for the handler might be rethrown on the UI SynchronizationContext, which usually crashes the application.



  • After you raise the event, the handlers won't be completed yet. The execution of a handler might be interleaved with the execution of the code after the raising and execution of multiple handlers can also be interleaved with each other.



Assuming those caveats are acceptable for you, code like this should be fine.

Also:

view.OnRefreshObjectExplorerClicked += new EventHandler(async (s, e) => await RefreshObjectExplorerAsync());


You should be able to simplify this to just:

view.OnRefreshObjectExplorerClicked += async (s, e) => await RefreshObjectExplorerAsync();


It seems you never unsubscribe the event handlers, are you sure that's okay?

Code Snippets

view.OnRefreshObjectExplorerClicked += new EventHandler(async (s, e) => await RefreshObjectExplorerAsync());
view.OnRefreshObjectExplorerClicked += async (s, e) => await RefreshObjectExplorerAsync();

Context

StackExchange Code Review Q#133464, answer score: 32

Revisions (0)

No revisions yet.