提问人:Mark Cidade 提问时间:10/11/2008 最后编辑:Coral DoeMark Cidade 更新时间:10/22/2022 访问量:2983
使用异步委托或 ThreadPool.QueueUserWorkItem 实现大规模并行性?
Use asynchronous delegates or ThreadPool.QueueUserWorkItem for massive parallelism?
问:
我有一个 .NET 应用程序,在批量导入中处理大约 300,000 条记录,每条记录需要几秒钟,因此我想并行化它。在下面的代码中,和有什么不一样?ProcessWithAnsycDelegates()
ProcessWithThreadPool()
public class ResultNotification
{ public EventHandler event Success;
public EventHandler event Fail;
internal void Notify(bool sucess) {if (success) Success(); else Fail();}
}
public static class Processor
{ public ResultNotification ProcessWithAnsycDelegates(Record record)
{ var r = new ResultNotification();
Func<Record,bool> processRecord=new RecordProcessor().ProcessRecord;
processRecord.BeginInvoke
( record
,ar => result.Notify(processRecord.EndInvoke(ar))
,null);
return r;
}
public ResultNotification ProcessWithThreadPool(Record r)
{ var r = new ResultNotification();
var rp = new RecordProcessor();
ThreadPool.QueueWorkUserItem(_=>result.Notify(rp.ProcessRecord(r)));
return r;
}
}
答:
6赞
chadmyers
10/11/2008
#1
在这种情况下,不是很多,因为它们都在后台使用线程池。我会说更容易阅读并查看发生了什么。QueueUserWorkItem()
BeginInvoke()
此链接可能会有所帮助。这是较旧的信息,但仍然最适用:https://jonskeet.uk/csharp/threads/threadpool.html
评论
0赞
bzlm
10/12/2008
哪些部分不适用?
7赞
Thomas Bratt
10/12/2008
#2
这个问题的字面答案是两者都使用线程池,因此如果性能是唯一的考虑因素,则差异不大。
如果问题真的是关于获得最佳性能,那么知道使用线程池确实存在问题可能会有所帮助。这些包括:
- 工作队列上的锁争用
- 过多的上下文切换。如果您有 2 个 CPU 和一系列工作项,那么 25 个线程并没有真正的帮助。最好有 2 个线程,每个 CPU 一个
可能值得研究 TPL 和 PLINQ:
他们给出的 TPL 使用的一个例子是:
for (int i = 0; i < 100; i++) {
a[i] = a[i]*a[i];
}
自:
Parallel.For(0, 100, delegate(int i) {
a[i] = a[i]*a[i];
});
评论