我在用 C# 编写异步多服务器网络应用程序时遇到了问题。我有很多工作由线程池处理,其中包括对网络套接字的写入。这最终允许多个线程可以同时写入套接字并打乱我的传出消息的情况。我解决这个问题的想法是实现一个队列系统,只要数据被添加到队列中,套接字就会写入它。
我的问题是,我无法完全理解这种性质的架构。我想象有一个队列对象,只要数据被添加到队列中就会触发一个事件。然后该事件将保存在队列中的数据写入,但这不会起作用,因为如果两个线程同时进入并添加到队列中,即使队列是线程安全的,事件仍然会被触发我会遇到同样的问题。因此,如果另一个事件正在进行中,也许可以通过某种方式推迟一个事件,但是一旦第一个事件结束,我该如何继续该事件,而不是简单地将线程阻塞在某个互斥锁或其他东西上。如果我不试图严格遵守我的“无阻塞”架构,这不会那么难,但这个特定的应用程序要求我允许线程池线程继续做他们的事情。
有什么想法吗?
最佳答案
虽然类似于 Porges 的答案,但在实现上略有不同。
首先,我通常不对要发送的字节进行排队,而是在发送线程中对对象进行序列化,但我想这是个人喜好问题。 但更大的区别在于 ConcurrentQueues 的使用(除了 BlockingCollection)。 所以我最终得到的代码类似于
BlockingCollection<Packet> sendQueue = new BlockingCollection<Packet>(new ConcurrentQueue<Packet>());
while (true)
{
var packet = sendQueue.Take(); //this blocks if there are no items in the queue.
SendPacket(packet); //Send your packet here.
}
这里的关键是你有一个循环这段代码的线程,所有其他线程都可以以线程安全的方式添加到队列中(BlockingCollection 和 ConcurrentQueue 都是线程安全的)
看看Processing a queue of items asynchronously in C#我在那里回答了类似的问题。
关于c# - 异步队列管理器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9678671/