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