在过去,我这样做过:
List<Item> _Items = GetItems();
int _CountDown = _Items.Count;
using (BackgroundWorker _Worker = new BackgroundWorker())
{
_Worker.DoWork += (s, arg) =>
{
DoSomething(_Items[_CountDown]);
};
_Worker.RunWorkerCompleted += (s, arg) =>
{
if (System.Threading.Interlocked.Decrement(ref _CountDown) == 0)
RaiseAllDoneEvent();
else
_Worker.RunWorkerAsync();
};
_Worker.RunWorkerAsync();
}平行地,我做了这样的事情:
List<Item> _Items = GetItems();
int _CountDown = _Items.Count;
System.Threading.Tasks.Parallel.ForEach(_Items, (i) =>
{
DoSomething(i);
if (System.Threading.Interlocked.Decrement(ref _CountDown) == 0)
RaiseAllDoneEvent();
});我真正的问题是:在这里Interlocked.Decrement()对吗?
发布于 2011-09-01 21:16:59
Parallel.ForEach将阻塞所有项,直到所有项都被处理--这里正确的做法似乎是在调用Parallel.ForEach之后立即从调用方调用RaiseAllDoneEvent():
List<Item> _Items = GetItems();
System.Threading.Tasks.Parallel.ForEach(_Items, (i) =>
{
DoSomething(i);
});
RaiseAllDoneEvent();换句话说,根本不需要计算下来(或者跟踪有多少项需要处理)。如果希望并行操作不被阻塞,可以将其转换为一组任务:
List<Item> _Items = GetItems();
Task.Factory.StartNew(()=> {
Task.WaitAll(
_Items.Select(i => Task.Factory.StartNew(() => DoSomething(i))).ToArray()
);
}).ContinueWith(t => RaiseAllDoneEvent());在这种情况下,您将启动一个外部任务来旋转,然后等待一组任务(每个项一个),然后最后引发all done事件。所有这些都不会阻止原来的调用者。
https://stackoverflow.com/questions/7276603
复制相似问题