我有一些代码可以作为一个轻量级,无阻塞,关键部分。我希望无论_func
和cancellationToken
子句中Task.Run
和Exit
发生什么情况,都可以保证继续运行finally
语句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();
}
})
}
块将始终执行。
是否可以安全地假设下面的finally块(缺少流程中的灾难性故障)将以与finally normal operates with大致相同的保证执行?
//Assumes ATABLE has been pre-initialized.
char[][] array = new char[ATABLE][ATABLE];
for (int row = 0; row < ATABLE; row++)
{
for(int col = 0; col < ATABLE; col++)
{
array[row][col] = ' ';
}
}
答案 0 :(得分:7)
在当前任务完成之前,返回的任务不会被安排执行,是否由于成功运行而完成,由于未处理的异常而导致错误,或者由于被取消而提前退出。
因此,除非_func
永远不会返回(例如在无限循环中运行),否则将继续运行。
当延续运行时,finally块将保证按照C#规则执行。
所以答案是肯定的(除非当然_func
永远不会返回)。
答案 1 :(得分:1)
如果在第一个任务运行之前取消了令牌,则继续将不会运行,因此finally将不会执行。在VS 2015中进行了测试:http://pastebin.com/9qmUYnqv
顺便提一下,编写的代码有一些设计问题 - 任务修改状态不是最好的主意;任务应该返回值和诸如此类的东西。在这种特殊情况下,对于非阻塞关键部分,请考虑使用SemaphoreSlim。