ホームページ > バックエンド開発 > C++ > C# イベントを非同期にする方法?

C# イベントを非同期にする方法?

Mary-Kate Olsen
リリース: 2025-01-08 12:31:41
オリジナル
676 人が閲覧しました

How to Make C# Events Asynchronous?

C# での非同期イベントのエレガントな処理

C# アプリケーションでは、クラスにイベント (「GameShuttingDown」イベントなど) が含まれており、イベント ハンドラーが非同期である場合、待機中のイベント ハンドラーが完了する前にゲームが終了するという問題が発生する可能性があります。これは、イベント自体は同期ですが、ハンドラーは非同期であるためです。

非同期メカニズムを使用してイベントを置き換えることは可能ですが、これによりイベントの単純さが失われます。より良いアプローチは、非同期処理を有効にしながらイベントの表現力を維持することです。 これは、標準の EventHandler を使用する代わりにデリゲートの型をカスタマイズすることで実現できます。

次の例はその方法を示しています。

<code class="language-csharp">public class A
{
    public event Func<object, EventArgs, Task> Shutdown;

    public async Task OnShutdown()
    {
        var handler = Shutdown;

        if (handler == null)
        {
            return;
        }

        var invocationList = handler.GetInvocationList();
        var handlerTasks = invocationList.Select(h => ((Func<object, EventArgs, Task>)h)(this, EventArgs.Empty)).ToArray();

        await Task.WhenAll(handlerTasks);
    }
}</code>
ログイン後にコピー

OnShutdown() メソッドでは、まずイベント デリゲートのローカル コピーを取得します。次に、すべてのハンドラーを呼び出し、返されたタスクを配列に格納します。最後に、Task.WhenAll() を使用して、すべてのタスクが完了するのを待ちます。 これはループ反復よりも簡潔です。

以下は、使用法を示す簡単なコンソール プログラムです:

<code class="language-csharp">public class Program
{
    public static void Main(string[] args)
    {
        var a = new A();

        a.Shutdown += Handler1;
        a.Shutdown += Handler2;
        a.Shutdown += Handler3;

        a.OnShutdown().Wait();
    }

    public static async Task Handler1(object sender, EventArgs e)
    {
        Console.WriteLine("启动关闭处理程序 #1");
        await Task.Delay(1000);
        Console.WriteLine("关闭处理程序 #1 完成");
    }

    public static async Task Handler2(object sender, EventArgs e)
    {
        Console.WriteLine("启动关闭处理程序 #2");
        await Task.Delay(5000);
        Console.WriteLine("关闭处理程序 #2 完成");
    }

    public static async Task Handler3(object sender, EventArgs e)
    {
        Console.WriteLine("启动关闭处理程序 #3");
        await Task.Delay(2000);
        Console.WriteLine("关闭处理程序 #3 完成");
    }
}</code>
ログイン後にコピー

このアプローチでは、イベントの単純さを維持しながら、ハンドラーが非同期で実行されるようにし、同期ブロックの問題を回避します。 LINQ の Select メソッドを使用するとコードが簡素化され、読みやすく保守しやすくなります。

以上がC# イベントを非同期にする方法?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
著者別の最新記事
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート