如何将工作封送到单线程 c# 上

本文关键字:单线程 工作 | 更新日期: 2023-09-27 18:34:14

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

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

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

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

如何将工作封送到单线程 c# 上

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

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

BlockingCollection<Packet> _packets = new BlockingCollection<Packet>();
...
while (true) {
    var packet = udp.GetNextPacket();
    _packets.Add(packet);
}

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

然后,创建一个工作线程,该线程执行与当前代码相同的操作,但它改为从块集合中读取。

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

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

如果您使用的是.Net 4,Tasks和TaskSchedulers可以在此处为您提供帮助。在 MSDN 上,您可以找到 LimitedConcurrencyLevelTaskScheduler。创建并发级别为 1 的单个实例,每次有工作要做时,创建一个 Task 并使用该计划程序对其进行计划。