在 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/