c# - 异步队列管理器

标签 c# architecture asynchronous queue asyncsocket

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

相关文章:

c# - EditorTemplate 中的 MVC 字典

c# - ReSharper 包装测试结果堆栈跟踪?

asp.net-mvc - ASP.NET MVC3 - 3 Tier design - 事务控制和业务层设计问题

c# - ASP.NET MVC 和 Azure 中具有通用代码的域和子域

c# - 具有多级嵌套关系版本控制的对象

c# - 涉及异步调用时如何跟踪工作单元?

c# - 向 Outlook 2010 功能区添加选项卡?

c# - 字符串到字节数组(到字符串到 XML)并再次返回

c# - 在 Azure Durable Functions 中,我如何适本地确定大量并行事件的进程?

java - 在 springboot async 中设置 maxpoolsize 会使我的 UI 仅对 5 个用户可用?