首页 > 后端开发 > C++ > 如何在 C# 中处理异步事件?

如何在 C# 中处理异步事件?

Mary-Kate Olsen
发布: 2025-01-08 12:37:42
原创
730 人浏览过

How to Handle Asynchronous Events in C#?

C#异步事件处理详解

引言

C#事件机制是处理异步操作的强大工具。然而,传统的事件是无返回值的(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()
{
    // ...
}</code>
登录后复制

问题在于,NotifyGameShuttingDown事件处理程序是无返回值的,在ShutdownGame方法中调用它会阻止异步保存任务在事件触发之前完成。

解决方案一:自定义异步事件委托

一种方法是定义一个返回Task的自定义事件委托,允许等待处理程序的执行:

<code class="language-csharp">public event Func<object, EventArgs, Task> Shutdown;</code>
登录后复制

ShutdownGame方法中,处理程序可以这样调用:

<code class="language-csharp">Func<object, EventArgs, Task> handler = Shutdown;

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>
登录后复制

解决方案二:基于注册的方法

另一种选择是使用基于注册的方法,其中可以异步注册和执行回调:

<code class="language-csharp">private List<Func<Task>> ShutdownCallbacks = new List<Func<Task>>();

public void RegisterShutdownCallback(Func<Task> callback)
{
    this.ShutdownCallbacks.Add(callback);
}

public async Task Shutdown()
{
    var callbackTasks = new List<Task>();
    foreach (var callback in this.ShutdownCallbacks)
    {
        callbackTasks.Add(callback());
    }

    await Task.WhenAll(callbackTasks);
}</code>
登录后复制

注意事项

  • 设计影响:使用异步事件处理程序可能会改变应用程序的设计,因此请仔细考虑潜在的影响。
  • 复杂性:自定义委托方法会增加额外的复杂性,但它确保与现有事件模式的兼容性。
  • 性能:基于注册的方法效率可能更高,因为它避免了在调用处理程序时反射带来的开销。

推荐

推荐的方法取决于应用程序的具体需求。对于现有代码库以及大量基于事件的设计,自定义委托方法是首选。对于新的应用程序或那些不依赖于事件的应用程序,基于注册的方法可以提供更好的性能和灵活性。

以上是如何在 C# 中处理异步事件?的详细内容。更多信息请关注PHP中文网其他相关文章!

来源:php.cn
本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
作者最新文章
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板