C# 根据数据库队列管理线程池的最佳方法
我有一个充满摘要条目的数据表,我的软件需要遍历并接触web服务以获取详细信息,然后将这些详细信息记录回数据库。调用web服务并等待响应时同步循环表的速度太慢(有数千个条目),因此我希望获取结果(一次10个左右)并执行线程,以便它同时执行10个操作 我在C#threads方面的经验至少是有限的,那么最好的方法是什么呢?NET是否有某种线程安全队列系统,我可以使用它来确保结果得到正确有序的处理 NET是否有某种线程安全队列系统,我可以使用它来确保结果得到正确有序的处理 这是在.NET4中添加的内容。默认情况下,该类充当生产者/消费者场景的线程安全队列C# 根据数据库队列管理线程池的最佳方法,c#,.net,database,winforms,multithreading,C#,.net,Database,Winforms,Multithreading,我有一个充满摘要条目的数据表,我的软件需要遍历并接触web服务以获取详细信息,然后将这些详细信息记录回数据库。调用web服务并等待响应时同步循环表的速度太慢(有数千个条目),因此我希望获取结果(一次10个左右)并执行线程,以便它同时执行10个操作 我在C#threads方面的经验至少是有限的,那么最好的方法是什么呢?NET是否有某种线程安全队列系统,我可以使用它来确保结果得到正确有序的处理 NET是否有某种线程安全队列系统,我可以使用它来确保结果得到正确有序的处理 这是在.NET4中添加的内容。
通过将一个或多个元素添加到集合中,可以很容易地从集合和流程中创建大量“消费”的元素。这取决于.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.
如果您使用的是.NET Framework 4.0,则可以使用
您使用的是什么版本的.Net?Net 4中的多线程编程有很大的改进。应该包括这一点。。目前的目标是3.5,但我可以毫无困难地实现4.0。非常好,我一定会去看看。谢谢那么并发队列呢@默认情况下,Dykam
BlockingCollection
包装一个ConcurrentQueue
。虽然您可以直接使用CQ,但如果您想在生产者/消费者场景中工作,如前所述,BC使这变得更加简单。顺便说一句,如果您从Microsoft网站下载反应式扩展后端口,您实际上可以使用3.5中的TPL。非常棒的东西——非常感谢大家。看来有几种方法可以剥这只猫的皮!只有一件事(我知道,我会选择RTFM!),但这是如何扩展的呢?我将执行数千行,我绝对不想同时启动数千个线程。我假设(希望?)有某种内置的限制,这样就不会让用户的计算机停止。@MitchellV:Thread.QueueUserWorkItem
和并行。ForEach
的伸缩性非常好Task.StartNew
通常可以很好地扩展,除了Task.WaitAll
在幕后使用WaitHandle.WaitAll
时可能有64个计数限制,但我认为不会。所有这些方法的核心都使用线程池技术,因此启动数千个工作项应该不是问题。
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.
Parallel.ForEach(table.Rows,
(DataRow row) =>
{
ProcessDataRow(row);
});