c# - 异步事件处理程序和并发

标签 c# task-parallel-library async-await

在 C# 控制台应用程序的上下文中,如果我创建一个用于异步接收消息的循环,它会为收到的每条消息引发一个事件,例如:

while (true)
{
   var message = await ReceiveMessageAsync();
   ReceivedMessage(new ReceivedMessageEventArgs(message));
}

现在,如果我有多个事件订阅者(为了示例,假设有 3 个订阅者),所有订阅者都使用异步事件处理程序,例如:

async void OnReceivedMessageAsync(object sender, ReceivedMessageEventArgs args)
{
   await TreatMessageAsync(args.Message);
}

消息对象应该以线程安全的方式编码吗?我认为是这样,因为来自不同事件处理程序的 TreatMessageAsync 代码可能会同时为所有订阅者运行(当事件被引发时,订阅者的三个异步事件处理程序被调用,每个都启动一个异步操作,该操作可能会在不同线程上同时运行由任务调度程序)。还是我错了?

谢谢!

最佳答案

您应该以线程安全的方式对其进行编码。最简单的方法是使其不可变。

如果您有一个真实的事件,那么它的参数应该是不可变的。如果您将事件处理程序用于不是真正的事件(例如命令实现),那么您可能需要修改您的API。

可以有并发事件处理程序,因为每个处理程序将按顺序开始,但它们可以同时恢复

关于c# - 异步事件处理程序和并发,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13634380/

相关文章:

c# - 在不破坏客户端代码的情况下将一个接口(interface)拆分为两个新接口(interface)?

c# - 数据流(任务并行库)和异步等待

c# - 我在哪里标记 lambda 表达式异步?

javascript - 有人可以解释为什么我需要在两个不同的函数中使用await来获取json吗?

c# - Excel 在 *.xlsx 中发现不可读的内容

C# 窗口渲染 PHP

c# - 在两个目的地复制流内容

c# - 在 react 性管道中执行TPL代码并通过测试计划程序控制执行

c# - 包括 Lambda 在内的异步/等待方法的正确方法

javascript - typescript Await 在回调中不起作用