ActionBlock 有时会错过动作
ActionBlock misses actions sometimes
我正在使用 ActionBlock
,我测试了它是否像下面一样正常工作,有时 Actionblock
错过了动作,这根本不应该发生
为什么会发生这种情况,我该如何解决?
var n = 0;
var action = new Action<int>((i) =>
{
n++;
//...job...
}
for (int i = 0; i < size; i++)
{
var block = new ActionBlock<int>(i => action(i),
new ExecutionDataflowBlockOptions { MaxDegreeOfParallelism = 6 });
n = 0;
foreach (var a in list)
block.Post(a);
block.Complete();
block.Completion.Wait();
if (n != list.Count)
ShowError(); //it's called sometimes
}
ActionBlock
可以并行方式执行操作(我相信它在您的情况下确实如此)。因此,在这种情况下,您只会在 n++
操作上发生数据竞争。
所以,实际上 ActionBlock
不会遗漏任何东西,但你只是错误地计算了 n
并且有时(可能几乎所有时间)最后得到错误的计数。
要获得 n
的正确值,您可以将 n++
替换为 Interlocked.Increment(ref n)
或仅添加 lock
.
我正在使用 ActionBlock
,我测试了它是否像下面一样正常工作,有时 Actionblock
错过了动作,这根本不应该发生
为什么会发生这种情况,我该如何解决?
var n = 0;
var action = new Action<int>((i) =>
{
n++;
//...job...
}
for (int i = 0; i < size; i++)
{
var block = new ActionBlock<int>(i => action(i),
new ExecutionDataflowBlockOptions { MaxDegreeOfParallelism = 6 });
n = 0;
foreach (var a in list)
block.Post(a);
block.Complete();
block.Completion.Wait();
if (n != list.Count)
ShowError(); //it's called sometimes
}
ActionBlock
可以并行方式执行操作(我相信它在您的情况下确实如此)。因此,在这种情况下,您只会在 n++
操作上发生数据竞争。
所以,实际上 ActionBlock
不会遗漏任何东西,但你只是错误地计算了 n
并且有时(可能几乎所有时间)最后得到错误的计数。
要获得 n
的正确值,您可以将 n++
替换为 Interlocked.Increment(ref n)
或仅添加 lock
.