我目前正在开发一个应用程序,它依赖于多个侦听聊天消息的套接字。当消息传入时,它们会被传递给与它们的通道相关联的机器人。由于这个bot有大量的通道,因此为每个bot创建一个线程是非常低效的。
理想情况下,我要寻找的是启动一个任务,该任务将在任务池中运行,以处理每个bot的消息。我希望有一个线程池,比如30-100个线程同时运行处理消息,但只有一个线程绑定到特定的bot (或套接字)。我读过一些有关任务并行库的文章,但我很困惑如何锁定特定的上下文。
一切都从这里开始:
IrcConnection.BeginReceive(state.Buffer, 0, state.Buffer.Length, SocketFlags.None, RecieveComplete, state);
//When a message comes in, it calls RecieveComplete, which invokes an event handler:
UserMessageRecieved?.Invoke(this, new UserMessageEventArgs(userMessage));
//And the event handler:
public async void bot_UserMessageRecieved(object sender, UserMessageEventArgs e)
现在,多个线程可以并发地访问单个bot上下文。防止这种情况发生的好办法是什么?TPL是进行这个项目的正确方式吗?
发布于 2017-02-26 10:14:57
根据您的问题,您需要一个代理来处理多个进程以并行发送和接收消息,但是处理这些消息必须具有异步行为,因为您正在处理I/O,大多数I/O操作(包括TCP套接字)通常是阻塞的,因此使用异步实现是最好的选择。
但是,如果使用事件异步模式( .NET EAP ),那么将并行操作与异步操作结合起来并不是一项容易的任务,您在问题中已经说明了这一点。我知道.NET EAP模型,因为在方法中使用的是Beginxxx和Endxxx模式。这反过来又使异步等待使用变得更加困难。这很困难,因为所有异步和等待操作都必须封装Beginxxx和Receivexx (或Endxxx)方法对。
您应该知道,在.NET 4.5和更高版本中,EAP模型现在被认为是遗留异步模型,只需查看下面的MSDN链接即可。
对于并行编程,它可以在NET (任务并行库)模型中使用。此.NET TPL只描述并行编程。如果要使用异步等待,则需要检查.NET TAP (任务异步模式)模型,这就是为什么.NET TAP与.NET TPL不完全相同的原因。
我建议您在.NET中使用现有的System.Net.Sockets
4.5 (及以上)套接字API (例如,只需查看具有异步后缀的TcpListener
's方法),然后将异步方法的每个执行合并到并行执行中。
第二,不要为你的机器人使用一个上下文。拥有并行编程意味着您应该知道您将有多个单独运行的执行上下文。只有一个上下文就会增加困难,因为您应该为不同的消息会话管理状态。不过,你的里程可能会有所不同。
最后一个建议:任何并发模型都没有单一的解决方案。
有关.NET EAP的更多信息,请访问:https://msdn.microsoft.com/en-us/library/ms228969(v=vs.110).aspx
有关.NET TAP的更多信息,请访问:https://msdn.microsoft.com/en-us/library/hh873175(v=vs.110).aspx
有关.NET TPL的更多信息,请访问:https://msdn.microsoft.com/en-us/library/dd460693(v=vs.110).aspx
更新1(根据评论):
任务调度器?是的,对于TPL中的任务调度程序/同步上下文,请访问TaskScheduler
TPL中的.NET示例:https://msdn.microsoft.com/en-us/library/system.threading.tasks.taskscheduler(v=vs.110).aspx
但是,在使用该类时,请确保在所有任务创建中都添加了CancellationToken
支持,否则,如果进程被锁定/超时,则会出现不可预测的行为。
如果您想要更多地控制并行操作的最大数量的排序和粒度,那么可以使用定制的并行执行组合.NET TPL中的并行编程。例如,您可以使用附加的Parallel.For和ParallelOptions
运行该ParallelLoopState
。
例如:请参阅Parallel.For
与ParallelOptions
使用的文档:https://msdn.microsoft.com/en-us/library/dd784105(v=vs.110).aspx
https://softwareengineering.stackexchange.com/questions/343024
复制相似问题