b2zw2a
b2zw2a

Reputation: 2693

Dataflow(TPL) - exception handling issue?

I'm not sure if i'm doing something wrong or it's an issue with Dataflow but I can't work out when Receive() throws exception. When I run this test:

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
        {
        }
    }
}

I'm getting inconsistent results, first run:

Xunit.Sdk.EqualExceptionAssert.Equal() Failure 
Expected: 1000 
Actual:  127

then run again:

Xunit.Sdk.EqualExceptionAssert.Equal() Failure
Expected: 1000
Actual:   14

Can someone confirm that it's not "on my machine" only issue?

Gist: https://gist.github.com/plentysmart/1c2ed2e925cc3f690f61

Upvotes: 1

Views: 415

Answers (1)

Stephen Cleary
Stephen Cleary

Reputation: 457472

Actually, I think the confusion is due to the OutputAvailableAsync behavior. This method will return false when there will never be any more output.

When a block faults (i.e., as the result of an exception from the transformation delegate), it will clear both input and output buffers. This causes OutputAvailableAsync to return false.

Upvotes: 2

Related Questions