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.