首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Interlocked.Decrement(i)对Parallel.ForEach()合适吗?

Interlocked.Decrement(i)对Parallel.ForEach()合适吗?
EN

Stack Overflow用户
提问于 2011-09-01 21:12:25
回答 1查看 560关注 0票数 2

在过去,我这样做过:

代码语言:javascript
复制
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();
}

平行地,我做了这样的事情:

代码语言:javascript
复制
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()对吗?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2011-09-01 21:16:59

Parallel.ForEach将阻塞所有项,直到所有项都被处理--这里正确的做法似乎是在调用Parallel.ForEach之后立即从调用方调用RaiseAllDoneEvent():

代码语言:javascript
复制
List<Item> _Items = GetItems();
System.Threading.Tasks.Parallel.ForEach(_Items, (i) =>
{
    DoSomething(i);
});
RaiseAllDoneEvent();

换句话说,根本不需要计算下来(或者跟踪有多少项需要处理)。如果希望并行操作不被阻塞,可以将其转换为一组任务:

代码语言:javascript
复制
List<Item> _Items = GetItems();
Task.Factory.StartNew(()=> { 
        Task.WaitAll(
            _Items.Select(i => Task.Factory.StartNew(() => DoSomething(i))).ToArray()
        ); 
    }).ContinueWith(t => RaiseAllDoneEvent());

在这种情况下,您将启动一个外部任务来旋转,然后等待一组任务(每个项一个),然后最后引发all done事件。所有这些都不会阻止原来的调用者。

票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/7276603

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档