C# 使用任务并行库

C# 使用任务并行库,c#,C#,我刚刚开始编写和使用.NET4.5中的TPL,不知道您是否可以帮助我 基本上,我的WPF程序对一组数据库记录执行繁重的工作,这些记录的范围可能在500万到1000万之间。 我想利用TPL库高效地管理这项工作,同时保持UI的响应性 我的场景如下,我计划使用3个单独的任务来检索数据,比如说每个300万,并将它们提供给我的“工作人员” 我想要一个单独的任务,从上述任务的所有项目中提取每个项目,并对其进行一些处理 所以我想要一个全局项目列表,所有3个任务都可以将项目放入其中,我的第四个任务,然后应该从主

我刚刚开始编写和使用.NET4.5中的TPL,不知道您是否可以帮助我

基本上,我的WPF程序对一组数据库记录执行繁重的工作,这些记录的范围可能在500万到1000万之间。 我想利用TPL库高效地管理这项工作,同时保持UI的响应性

我的场景如下,我计划使用3个单独的任务来检索数据,比如说每个300万,并将它们提供给我的“工作人员”

我想要一个单独的任务,从上述任务的所有项目中提取每个项目,并对其进行一些处理

所以我想要一个全局项目列表,所有3个任务都可以将项目放入其中,我的第四个任务,然后应该从主列表中一次选取一个项目,并对其进行一些处理,如果列表为空,它应该等待再次填充,等等


请您提供一些关于如何使用TPL的指导?我是TPL的新手。一些示例代码会很好。

考虑将每个
任务中的项目存储在全局线程安全的列表对象中,如
ConcurrentStack
ConcurrentQueue


有关更多信息,请参见:

如果我正确理解了问题描述,您有一个生产者/消费者场景,其中有三个生产者,每个生产者从数据库中检索独立记录,还有一个消费者

如果是这种情况,那么在我看来,您应该从
BlockingCollection
开始,其中
T
是生产者从数据库检索的对象类型。要使用的基础集合取决于您希望如何处理数据。最常见的场景是FIFO和无序,分别由
ConcurrentQueue
ConcurrentBag
表示

下面是一个简单的代码示例,演示了该方法的工作原理:

BlockingCollection<int> consumeFrom = new BlockingCollection<int>();
int producerCount = 3;

for (int i = 0; i < producerCount; i++)
{
    int taskValue = i;

    // Make dummy task for example
    Task.Run(() =>
    {
        for (int j = 0; j < 10; j++)
        {
            Thread.Sleep(1000);
            consumeFrom.Add(taskValue * 10 + j);
        }

        if (Interlocked.Decrement(ref producerCount) == 0)
        {
            consumeFrom.CompleteAdding();
        }
    });
}

foreach (int i in consumeFrom.GetConsumingEnumerable())
{
    Console.WriteLine(i);
}
BlockingCollection consumerfrom=new BlockingCollection();
int producerCount=3;
for(int i=0;i
{
对于(int j=0;j<10;j++)
{
睡眠(1000);
consumerfrom.Add(taskValue*10+j);
}
if(联锁减量(参考生产计数)==0)
{
consumerfrom.CompleteAdding();
}
});
}
foreach(consumerfrom.getconsumineGenumerable()中的int i)
{
控制台写入线(i);
}
请注意,这使用默认的基础数据源
ConcurrentQueue
。您可以向
BlockingCollection
构造函数提供
IProducerConsumerCollection
的其他实现,例如:

BlockingCollection<int> consumeFrom =
    new BlockingCollection<int>(new ConcurrentBag<int>());
BlockingCollection-from=
新的BlockingCollection(新的ConcurrentBag());

这听起来很复杂。在数据库的结果流上运行Parallel.ForEach循环怎么样?这取决于需要处理的工作类型。对于CPU密集型计算,Parallel.ForEach()可能是正确的选择。对于I/O绑定(例如文件和数据库连接),等待异步方法的操作将更加有效。