TPL 数据流块中抛出的 OperationCanceledException 被吞没
OperationCanceledException thrown in tpl dataflow block gets swallowed
出于某种原因,当 OperationCanceledException
被抛入 IDataflowBlock
时,该块不会将此异常传播到其 IDataflowBlock.Completion
任务。 运行 下面的代码示例 returns 出乎意料 IDataflowBlock.Completion.Status == TaskStatus.RanToCompletion
。
但是,如果块中抛出的异常类型更改为 ArgumentNullException
,则 IDataflowBlock.Completion.Status
更改为 TaskStatus.Faulted
并且异常保存在其 InnerException
中属性。
知道为什么 OperationCanceledException
会被吞掉吗?
[TestFixture]
public class TplDataBlockExceptionTest
{
[Test]
public void ShouldThrowException()
{
// Arrange
var block = new TransformBlock<int, string>(i =>
{
throw new OperationCanceledException();
return i.ToString();
});
// Act
block.Post(1);
block.Complete();
try
{
block.Completion.Wait();
}
catch (Exception)
{
// ignored
}
// Assert
Assert.That(block.Completion.IsFaulted);
}
}
出于某种原因,当 OperationCanceledException
被抛入 IDataflowBlock
时,该块不会将此异常传播到其 IDataflowBlock.Completion
任务。 运行 下面的代码示例 returns 出乎意料 IDataflowBlock.Completion.Status == TaskStatus.RanToCompletion
。
但是,如果块中抛出的异常类型更改为 ArgumentNullException
,则 IDataflowBlock.Completion.Status
更改为 TaskStatus.Faulted
并且异常保存在其 InnerException
中属性。
知道为什么 OperationCanceledException
会被吞掉吗?
[TestFixture]
public class TplDataBlockExceptionTest
{
[Test]
public void ShouldThrowException()
{
// Arrange
var block = new TransformBlock<int, string>(i =>
{
throw new OperationCanceledException();
return i.ToString();
});
// Act
block.Post(1);
block.Complete();
try
{
block.Completion.Wait();
}
catch (Exception)
{
// ignored
}
// Assert
Assert.That(block.Completion.IsFaulted);
}
}