如何使用线程处理多个任务

6

我有一个使用C#处理“大量”记录(可能> 100,000条)的需求。顺序运行此进程非常缓慢,每个记录需要约一秒钟才能完成(设置了5秒的超时错误)。

我想尝试通过使用一组工人“线程”异步运行这些任务(在此谨慎使用术语“线程”,因为我不确定是否应该查看线程、任务或其他内容)。

我已经查看了ThreadPool,但我无法想象它能够排队需要的请求量。我的理想伪代码将如下所示...

public void ProcessRecords() {
    SetMaxNumberOfThreads(20);
    MyRecord rec;
    while ((rec = GetNextRecord()) != null) {
        var task = WaitForNextAvailableThreadFromPool(ProcessRecord(rec));
        task.Start()
    }
}

我还需要一个机制,使处理方法能够向父/调用类报告。

有人可以给我指点方向,提供一些示例代码吗?


你为什么想要回报? - i3arnon
我想返回一个简单的 POCO 类,其中包含几个整数和一个字符串。这些数据将用于在进程运行时更新 UI。 - Neilski
你的处理是IO绑定还是CPU绑定? - Yuval Itzchakov
你为每个记录创建这个 POCO 吗? - i3arnon
2
看看TPL中还有什么可用的。这是可能存在的最简单的数据并行情况。 - usr
显示剩余4条评论
2个回答

9

一个可能简单的解决方案是使用TPL Dataflow块,它是TPL的更高级抽象,具有并行度等配置。您只需创建块(在此情况下为ActionBlock),将所有内容Post到其中,异步等待完成,TPL Dataflow会为您处理剩下的所有工作:

var block = new ActionBlock<MyRecord>(
    rec => ProcessRecord(rec), 
    new ExecutionDataflowBlockOptions{MaxDegreeOfParallelism = 20});

MyRecord rec;
while ((rec = GetNextRecord()) != null)
{
     block.Post(rec);
}

block.Complete();
await block.Completion

另一个好处是,块一旦接收到第一条记录就开始工作,而不仅仅是在接收到所有记录后才开始工作。
如果您需要对每个记录进行报告,可以使用TransformBlock来进行实际处理,并将ActionBlock链接到它以进行更新:
var transform = new TransfromBlock<MyRecord, Report>(rec =>
{
    ProcessRecord(rec);
    return GenerateReport(rec);
}, new ExecutionDataflowBlockOptions{MaxDegreeOfParallelism = 20});

var reporter = new ActionBlock<Report>(report =>
{
    RaiseEvent(report) // Or any other mechanism...
});

transform.LinkTo(reporter, new DataflowLinkOptions { PropagateCompletion = true });

MyRecord rec;
while ((rec = GetNextRecord()) != null)
{
     transform.Post(rec);
}

transform.Complete();
await transform.Completion

1
这个非常好用 - 非常感谢您花时间详细说明方法 - 非常感激。 - Neilski
@Neilski 当然可以,随时欢迎。 - i3arnon

1

您是否考虑过在操作中使用并行处理?例如,创建一个处理单个记录的方法,将每个记录方法添加到列表中作为一个操作,然后对该列表执行并行处理。

Dim list As New List(Of Action)
list.Add(New Action(Sub() MyMethod(myParameter)))
Parallel.ForEach(list, Sub(t) t.Invoke())

这是用vb.net编写的,但我想你已经明白了大意。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接