首頁 > 後端開發 > C++ > 如何使用非同步委託處理 C# 中的非同步事件?

如何使用非同步委託處理 C# 中的非同步事件?

Barbara Streisand
發布: 2025-01-08 12:41:41
原創
990 人瀏覽過

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

C#非同步委託:優雅地等待非同步事件

在C#中,事件傳統上傳回void,這使得它們與非同步操作不相容。當事件處理程序需要在通知其他元件之前執行非同步任務時,就會出現這個問題。以下場景探討了這個問題,並提供了一個使用非同步委託的解決方案。

問題:

下面的程式碼示範了一個名為GameShuttingDown的事件,該事件在遊戲關閉時觸發。每個事件處理程序都應該在遊戲關閉之前非同步保存資料。但是,處理程序使用void方法調用,導致遊戲在儲存完成之前關閉。

<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>
登入後複製

解:

為了解決這個問題,我們可以使用返回任務的非同步委託。這樣,我們可以非同步呼叫處理程序並等待結果。

將現有的GameShuttingDown事件替換為非同步委託類型:

<code class="language-csharp">public event Func<object, EventArgs, Task> GameShuttingDown;</code>
登入後複製

修改NotifyGameShuttingDown方法以呼叫處理程序並等待其完成:

<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>
登入後複製

用法:

使用新的非同步委託類型訂閱GameShuttingDown事件:

<code class="language-csharp">DefaultGame.GameShuttingDown += async (sender, args) => await this.repo.Save(blah);</code>
登入後複製

這種方法確保了遊戲只有在事件處理程序中所有非同步保存作業完成後才會關閉。

以上是如何使用非同步委託處理 C# 中的非同步事件?的詳細內容。更多資訊請關注PHP中文網其他相關文章!

來源:php.cn
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
作者最新文章
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板