Home > Backend Development > C++ > How to Handle Asynchronous Events in C# Using Async Delegates?

How to Handle Asynchronous Events in C# Using Async Delegates?

Barbara Streisand
Release: 2025-01-08 12:41:41
Original
988 people have browsed it

How to Handle Asynchronous Events in C# Using Async Delegates?

C# asynchronous delegate: gracefully wait for asynchronous events

In C#, events traditionally return void, which makes them incompatible with asynchronous operations. This problem arises when an event handler needs to perform an asynchronous task before notifying other components. The following scenario explores this problem and provides a solution using an asynchronous delegate.

Question:

The code below demonstrates an event named GameShuttingDown that fires when the game is closed. Each event handler should save data asynchronously before the game is closed. However, the handler is called with a void method, causing the game to close before the save completes.

<code class="language-csharp">public event EventHandler<EventArgs> GameShuttingDown;

public async Task ShutdownGame()
{
    await this.NotifyGameShuttingDown();
    await this.SaveWorlds();
    this.NotifyGameShutDown();
}

private async Task SaveWorlds()
{
    foreach (DefaultWorld world in this.Worlds)
    {
        await this.worldService.SaveWorld(world);
    }
}

protected virtual void NotifyGameShuttingDown()
{
    var handler = this.GameShuttingDown;
    if (handler == null)
    {
        return;
    }

    handler(this, new EventArgs());
}</code>
Copy after login

Solution:

To solve this problem, we can use an asynchronous delegate that returns a task. This way we can call the handler asynchronously and wait for the result.

Replace the existing GameShuttingDown event with an asynchronous delegate type:

<code class="language-csharp">public event Func<object, EventArgs, Task> GameShuttingDown;</code>
Copy after login

Modify the NotifyGameShuttingDown method to call the handler and wait for it to complete:

<code class="language-csharp">protected virtual async Task NotifyGameShuttingDown()
{
    Func<object, EventArgs, Task> handler = GameShuttingDown;

    if (handler == null)
    {
        return;
    }

    Delegate[] invocationList = handler.GetInvocationList();
    Task[] handlerTasks = new Task[invocationList.Length];

    for (int i = 0; i < invocationList.Length; i++)
    {
        handlerTasks[i] = ((Func<object, EventArgs, Task>)invocationList[i])(this, EventArgs.Empty);
    }

    await Task.WhenAll(handlerTasks);
}</code>
Copy after login

Usage:

Subscribe to GameShuttingDown events using the new asynchronous delegate type:

<code class="language-csharp">DefaultGame.GameShuttingDown += async (sender, args) => await this.repo.Save(blah);</code>
Copy after login

This approach ensures that the game will only close after all asynchronous save operations in the event handler have completed.

The above is the detailed content of How to Handle Asynchronous Events in C# Using Async Delegates?. For more information, please follow other related articles on the PHP Chinese website!

source:php.cn
Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Latest Articles by Author
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template