管理数据库队列的线程池的最佳方法

Mit*_*l V 8 .net c# database multithreading winforms

我有一个包含摘要条目的数据表,我的软件需要通过并访问Web服务以获取详细信息,然后将这些详细信息记录回数据库.通过表循环同步而调用Web服务,并等待响应太慢(每次10个左右),(有成千上万的条目),所以我想利用的结果并拧出来,所以它执行10同时进行操作.

我对C#线程的体验至少可以说,所以最好的方法是什么?.NET是否有某种线程安全队列系统,我可以用它来确保结果得到正确处理并按顺序排列?

Ree*_*sey 5

.NET是否有某种线程安全队列系统,我可以用它来确保结果得到正确处理并按顺序排列?

这是.NET 4中添加的内容.BlockingCollection<T>默认情况下,该类充当生产者/消费者方案的线程安全队列.

它使得从集合和流程中"消耗"的一些元素相当容易,并且一个或多个元素添加到集合中.


Bri*_*eon 5

根据.NET Framework的哪个版本,您有两个不错的选择.

您可以ThreadPool.QueueUserWorkItem在任何版本中使用.

int pending = table.Rows.Count;
var finished = new ManualResetEvent(false);
foreach (DataRow row in table.Rows)
{
  DataRow capture = row; // Required to close over the loop variable correctly.
  ThreadPool.QueueUserWorkItem(
    (state) =>
    {
      try
      {
        ProcessDataRow(capture);
      }
      finally
      {
         if (Interlocked.Decrement(ref pending) == 0) 
         {
           finished.Set();  // Signal completion of all work items.
         }
      }
    }, null);
}
finished.WaitOne(); // Wait for all work items to complete.
Run Code Online (Sandbox Code Playgroud)

如果您使用的是.NET Framework 4.0,则可以使用任务并行库.

var tasks = new List<Task>();
foreach (DataRow row in table.Rows)
{
  DataRow capture = row; // Required to close over the loop variable correctly.
  tasks.Add(
    Task.Factory.StartNew(
      () =>
      {
        ProcessDataRow(capture);        
      }));
}
Task.WaitAll(tasks.ToArray()); // Wait for all work items to complete.
Run Code Online (Sandbox Code Playgroud)

还有许多其他合理的方法可以做到这一点.我突出了上面的模式,因为它们很容易并且运行良好.在没有具体细节的情况下,我无法确定这两者是否适合您的情况,但它们应该是一个很好的起点.

更新:

我有一段短暂的脑低下脑活动.如果您有TPL可用,您也可以使用Parallel.ForEachTask我上面提到的所有hocus-pocus 更简单的方法.

Parallel.ForEach(table.Rows,
  (DataRow row) =>
  {
    ProcessDataRow(row);
  });
Run Code Online (Sandbox Code Playgroud)