2

我有一个应用程序需要处理来自 UDP 广播的一些数据包,并将结果写入 SQL 数据库。在间隔期间,传入数据包的速率变得非常高,并且我发现底层缓冲区溢出,即使是 8MB,因为数据库写入速度很慢。

为了解决这个问题,我提出了两个选项,缓存一些数据库写入,和/或将数据库写入编组到另一个顺序操作线程。(必须保留数据库写入的顺序)。

我的问题是如何使用 c# 的内置结构/功能最有效地编组工作?

我是否应该只拥有一个同步队列,将委托工作项放在它上面,并在事件循环中让一个线程为它服务?

4

2 回答 2

2

最简单的方法是为 UDP 读取创建一个单独的线程。

线程只是接收包并将它们放入 BlockingCollection。(不知道你是如何读取数据包的,所以这将是伪代码)

BlockingCollection<Packet> _packets = new BlockingCollection<Packet>();
...

while (true) {
    var packet = udp.GetNextPacket();
    _packets.Add(packet);
}

这将确保您不会因为阅读线程很忙而错过任何包裹。

然后,您创建一个工作线程,它与您当前的代码执行相同的操作,但它从blockingcollection 中读取。

while (true) {
   var nextPacket = _packets.Take();
   ...
}

如果您的包是独立的(因为您使用 UDP,它们应该是独立的),您可以启动多个工作线程。

于 2012-05-16T11:19:59.057 回答
1

如果您使用的是 .Net 4,Tasks 和 TaskScheduler可以在这里为您提供帮助。在 MSDN 上,您会找到LimitedConcurrencyLevelTask​​Scheduler。创建一个并发级别为 1 的单个实例,每次您有工作要做时,创建一个任务并使用该调度程序安排它。

于 2012-05-16T08:57:53.627 回答