gpt4 book ai didi

c# - Interlocked.Decrement(i)是否适合Parallel.ForEach()?

转载 作者:行者123 更新时间:2023-12-03 12:49:53 25 4
gpt4 key购买 nike

在过去,我这样做:

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();
}

使用Parallel,我可以做这样的事情:
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()正确吗?

最佳答案

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());

在这种情况下,您将启动一个外部任务以加快速度,然后等待一堆任务(每个项目一项),然后最终引发所有完成的事件。这些都不会阻止原始调用者。

关于c# - Interlocked.Decrement(i)是否适合Parallel.ForEach()?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7276603/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com