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

本文关键字:多任务 处理 线程 何使用 | 更新日期: 2023-09-27 18:36:57

我有一个 C# 要求单独处理"大量"(可能> 100,000 条)记录。按顺序运行此过程被证明非常慢,每条记录需要一秒钟左右才能完成(超时错误设置为 5 秒)。

我想尝试通过使用一定数量的工作线程"异步运行这些任务(我在这里谨慎使用术语"线程",因为我不确定我是否应该查看线程、任务或其他东西)。

我已经查看了ThreadPool,但我无法想象它可以排队所需的请求量。 我理想的伪代码看起来像这样...

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

我还需要一种机制,使处理方法可以向父/调用类报告。

任何人都可以用一些示例代码为我指出正确的方向吗?

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

一个可能的简单解决方案是使用 TPL 数据流块,它是 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

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

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

这是 vb.net,但我认为你明白了要点。