繁体   English   中英

异步队列管理器

[英]Asynchronous Queue Manager

我在c#中编写异步多服务器网络应用程序时遇到了问题。 我有许多工作由线程池处理,其中包括对网络套接字的写入。 这最终允许多个线程可以同时写入套接字并解除我的传出消息的情况。 我想解决这个问题的方法是实现一个队列系统,每当数据被添加到队列时,套接字就会编写它。

我的问题是,我无法完全围绕这种性质的架构。 我想有一个队列对象,只要数据被添加到队列就会触发事件。 然后事件将队列中保存的数据写入,但是这不起作用,因为如果有两个线程同时添加到队列中,即使队列是线程安全的,事件仍然会被激活,我会遇到同样的问题。 因此,如果另一个事件正在进行中,那么可能会推迟一个事件,但是如果第一个事件完成后如何继续该事件而不是简单地阻止一些互斥体上的线程。 如果我不想严格控制我的“无块”架构,这就不会那么难了,但是这个特殊的应用程序要求我允许线程池线程继续做他们的事情。

有任何想法吗?

听起来你需要一个线程同步写入套接字并且一堆线程写入队列以供该线程处理。

您可以使用阻塞集合( BlockingCollection<T> )来完成艰苦的工作:

// somewhere there is a queue:

BlockingCollection<byte[]> queue = new BlockingCollection<byte[]>();

// in socket-writing thread, read from the queue and send the messages:

foreach (byte[] message in queue.GetConsumingEnumerable())
{
    // just an example... obviously you'd need error handling and stuff here
    socket.Send(message);
}

// in the other threads, just enqueue messages to be sent:

queue.Add(someMessage);

BlockingCollection将处理所有同步。 您还可以强制执行最大队列长度和其他有趣的事情。

虽然与Porges相似,但它的实现有所不同。

首先,我通常不会将字节排队发送,而是在发送线程中对象和seralize它们,但我想这是一个品味问题。 但更大的区别在于使用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都是线程安全的)

看看在C#异步处理项目队列 ,我回答了类似的问题。

我不知道C#,但我要做的是让事件触发套接字管理器开始从队列中拉出来并一次写出一个。 如果它已经发生,则触发器将不执行任何操作,并且一旦队列中没有任何内容,它就会停止。

这解决了两个线程同时写入队列的问题,因为第二个事件是无操作。

您可以拥有一个线程安全的队列,所有工作线程都将其结果写入。 然后有另一个线程轮询队列并在看到它们等待时发送结果。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM