Heim > Backend-Entwicklung > C++ > Wie behandelt man asynchrone Ereignisse in C# mithilfe von asynchronen Delegaten?

Wie behandelt man asynchrone Ereignisse in C# mithilfe von asynchronen Delegaten?

Barbara Streisand
Freigeben: 2025-01-08 12:41:41
Original
990 Leute haben es durchsucht

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

Asynchroner C#-Delegat: Warten Sie elegant auf asynchrone Ereignisse

In C# geben Ereignisse traditionell „void“ zurück, was sie mit asynchronen Vorgängen inkompatibel macht. Dieses Problem tritt auf, wenn ein Ereignishandler eine asynchrone Aufgabe ausführen muss, bevor er andere Komponenten benachrichtigt. Das folgende Szenario untersucht dieses Problem und bietet eine Lösung mithilfe eines asynchronen Delegaten.

Frage:

Der folgende Code zeigt ein Ereignis namens GameShuttingDown, das ausgelöst wird, wenn das Spiel geschlossen wird. Jeder Event-Handler sollte Daten asynchron speichern, bevor das Spiel geschlossen wird. Allerdings wird der Handler mit einer void-Methode aufgerufen, was dazu führt, dass das Spiel geschlossen wird, bevor der Speichervorgang abgeschlossen ist.

<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>
Nach dem Login kopieren

Lösung:

Um dieses Problem zu lösen, können wir einen asynchronen Delegaten verwenden, der eine Aufgabe zurückgibt. Auf diese Weise können wir den Handler asynchron aufrufen und auf das Ergebnis warten.

Ersetzen Sie das vorhandene GameShuttingDown-Ereignis durch einen asynchronen Delegatentyp:

<code class="language-csharp">public event Func<object, EventArgs, Task> GameShuttingDown;</code>
Nach dem Login kopieren

Ändern Sie die Methode NotifyGameShuttingDown, um den Handler aufzurufen, und warten Sie, bis der Vorgang abgeschlossen ist:

<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>
Nach dem Login kopieren

Verwendung:

Abonnieren Sie GameShuttingDown Ereignisse mit dem neuen asynchronen Delegatentyp:

<code class="language-csharp">DefaultGame.GameShuttingDown += async (sender, args) => await this.repo.Save(blah);</code>
Nach dem Login kopieren

Dieser Ansatz stellt sicher, dass das Spiel erst geschlossen wird, nachdem alle asynchronen Speichervorgänge im Event-Handler abgeschlossen wurden.

Das obige ist der detaillierte Inhalt vonWie behandelt man asynchrone Ereignisse in C# mithilfe von asynchronen Delegaten?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Quelle:php.cn
Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
Neueste Artikel des Autors
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage