C# 数据流(TPL)-异常处理问题?

C# 数据流(TPL)-异常处理问题?,c#,async-await,tpl-dataflow,C#,Async Await,Tpl Dataflow,我不确定我是否做错了什么,或者这是数据流的问题,但我无法确定何时抛出异常。 当我运行此测试时: public class AsyncProblem { [Fact] public void AsyncVsAwaiterProblem() { var max = 1000; var noOfExceptions = 0; for (int i = 0; i < max; i++) {

我不确定我是否做错了什么,或者这是数据流的问题,但我无法确定何时抛出异常。 当我运行此测试时:

public class AsyncProblem
{
    [Fact]
    public void AsyncVsAwaiterProblem()
    {
        var max = 1000;
        var noOfExceptions = 0;
        for (int i = 0; i < max; i++)
        {
            try
            {
                Await().Wait();
            }
            catch
            {
                noOfExceptions++;
            }
        }
        Assert.Equal(max,noOfExceptions);
    }

    public async Task Await()
    {
        bool firstPassed = false;
        var divideBlock = new TransformBlock<int, int>((x) =>
        {
            if (firstPassed)
                throw new ArgumentException("error");
            firstPassed = true;
            return 0;
        });
        divideBlock.Post(2);
        divideBlock.Post(3); // this should cause failure;
        divideBlock.Complete();

        while (await divideBlock.OutputAvailableAsync())
        {
                var value = divideBlock.Receive(); // this should throw exception on second call
        }
        try
        {
            divideBlock.Completion.Wait();
        }
        catch
        {
        }
    }
}
然后再次运行:

Xunit.Sdk.EqualExceptionAssert.Equal() Failure
Expected: 1000
Actual:   14
有人能确认这不是“在我的机器上”唯一的问题吗


要点:

实际上,我认为混淆是由于
输出可用异步
行为造成的。当不再有任何输出时,此方法将返回
false


当一个块发生故障时(即,由于转换委托的异常),它将清除输入和输出缓冲区。这会导致
OutputAvailableAsync
返回
false

noOfExceptions
不是线程安全的。尝试使用
Interlocked.Increment
。谢谢,但此代码是连续的-Wait()确保当前任务已完成。是的,它看起来像是
OutputAvailableAsync
有时返回
true
,有时返回
false
错误块,只是不确定它是设计的还是错误。你有过同样不一致的行为吗?没有;我所看到的与
OutputAvailableAsync
一致,在块出现故障时总是返回
false
。请记住,测试中存在争用条件,因为
TransformBlock
在线程池上运行其委托。因此,只有当
TransformBlock
处理第一个输入并生成第一个输出时,您才会看到(少量)异常,因此
OAA
返回
true
,但随后调用
Receive
之前的块故障。如果块处理两个输入,则
OAA
返回
false
。我能够在另一台机器上重现问题(速度更快)。很难重现,但仍然得到了不一致的结果:
Xunit.Sdk.EqualExceptionAssert.Equal()预期失败:100000实际:2
注意,我必须将max更改为100000获取此结果。我已更新了。它运行的时间更长,但我每次都会遇到这个问题。
Xunit.Sdk.EqualExceptionAssert.Equal() Failure
Expected: 1000
Actual:   14