我有一个应用程序需要处理来自 UDP 广播的一些数据包,并将结果写入 SQL 数据库。在间隔期间,传入数据包的速率变得非常高,并且我发现底层缓冲区溢出,即使是 8MB,因为数据库写入速度很慢。
为了解决这个问题,我提出了两个选项,缓存一些数据库写入,和/或将数据库写入编组到另一个顺序操作线程。(必须保留数据库写入的顺序)。
我的问题是如何使用 c# 的内置结构/功能最有效地编组工作?
我是否应该只拥有一个同步队列,将委托工作项放在它上面,并在事件循环中让一个线程为它服务?
我有一个应用程序需要处理来自 UDP 广播的一些数据包,并将结果写入 SQL 数据库。在间隔期间,传入数据包的速率变得非常高,并且我发现底层缓冲区溢出,即使是 8MB,因为数据库写入速度很慢。
为了解决这个问题,我提出了两个选项,缓存一些数据库写入,和/或将数据库写入编组到另一个顺序操作线程。(必须保留数据库写入的顺序)。
我的问题是如何使用 c# 的内置结构/功能最有效地编组工作?
我是否应该只拥有一个同步队列,将委托工作项放在它上面,并在事件循环中让一个线程为它服务?
最简单的方法是为 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,它们应该是独立的),您可以启动多个工作线程。
如果您使用的是 .Net 4,Tasks 和 TaskScheduler可以在这里为您提供帮助。在 MSDN 上,您会找到LimitedConcurrencyLevelTaskScheduler。创建一个并发级别为 1 的单个实例,每次您有工作要做时,创建一个任务并使用该调度程序安排它。