Maison > développement back-end > C++ > Comment gérer les événements asynchrones en C# à l'aide de délégués asynchrones ?

Comment gérer les événements asynchrones en C# à l'aide de délégués asynchrones ?

Barbara Streisand
Libérer: 2025-01-08 12:41:41
original
990 Les gens l'ont consulté

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

Délégué asynchrone C# : attendez gracieusement les événements asynchrones

En C#, les événements renvoient traditionnellement void, ce qui les rend incompatibles avec les opérations asynchrones. Ce problème survient lorsqu'un gestionnaire d'événements doit effectuer une tâche asynchrone avant d'en informer d'autres composants. Le scénario suivant explore ce problème et fournit une solution à l’aide d’un délégué asynchrone.

Question :

Le code ci-dessous montre un événement nommé GameShuttingDown qui se déclenche lorsque le jeu est fermé. Chaque gestionnaire d'événements doit sauvegarder les données de manière asynchrone avant la fermeture du jeu. Cependant, le gestionnaire est appelé avec une méthode void, provoquant la fermeture du jeu avant la fin de la sauvegarde.

<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>
Copier après la connexion

Solution :

Pour résoudre ce problème, nous pouvons utiliser un délégué asynchrone qui renvoie une tâche. De cette façon, nous pouvons appeler le gestionnaire de manière asynchrone et attendre le résultat.

Remplacez l'événement GameShuttingDown existant par un type de délégué asynchrone :

<code class="language-csharp">public event Func<object, EventArgs, Task> GameShuttingDown;</code>
Copier après la connexion

Modifiez la méthode NotifyGameShuttingDown pour appeler le gestionnaire et attendez qu'elle se termine :

<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>
Copier après la connexion

Utilisation :

Abonnez-vous aux événements GameShuttingDown en utilisant le nouveau type de délégué asynchrone :

<code class="language-csharp">DefaultGame.GameShuttingDown += async (sender, args) => await this.repo.Save(blah);</code>
Copier après la connexion

Cette approche garantit que le jeu ne se fermera qu'une fois toutes les opérations de sauvegarde asynchrones dans le gestionnaire d'événements terminées.

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

source:php.cn
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Derniers articles par auteur
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal