我有一些代码作为一个轻量级的,非阻塞的,关键的部分。我希望无论_func和cancellationToken在Task.Run子句中发生了什么,都可以保证继续运行,以便始终执行其finally块中的Exit语句。
是否可以安全地假设下面的最后块(除了过程中的灾难性故障)将在与最后正常操作大致相同的保证下执行
if (Enter())
{
Task.Run<T>(_func, cancellationToken)
.ContinueWith((antecedent) =>
{
try
{
antecedent.Wait(cancellationToken);
Interlocked.Exchange<T>(ref _result, antecedent.Result);
}
catch (AggregateException e)
{
Interlocked.Exchange(ref _exceptions, e);
}
catch (OperationCanceledException)
{
ResetState();
}
catch (Exception e)
{
Interlocked.Exchange(ref _exceptions, new AggregateException(e));
}
finally
{
Exit();
}
})
}发布于 2016-02-20 00:29:34
基于MSDN文档
返回的任务在当前任务完成之前不会计划执行,无论是由于成功地运行到完成,还是由于未处理的异常而导致故障,还是由于被取消而提前退出。
因此,除非_func从不返回(例如,在无限循环中运行),否则继续将始终运行。
当继续运行时,最终块保证按照C#的规则执行。
因此,答案是肯定的(当然,除非_func永远不会返回)。
发布于 2016-02-20 00:47:29
如果令牌在第一个任务运行之前被取消,则继续将不会运行,因此最终不会执行。用VS 2015:http://pastebin.com/9qmUYnqv在这里测试
顺便说一句,在编写代码时存在一些设计问题--让任务修改状态不是最好的主意;任务应该返回值等等。在这种情况下,对于非阻塞临界部分,请考虑使用SemaphoreSlim。
https://stackoverflow.com/questions/35517519
复制相似问题