继续保证执行

本文关键字:执行 继续 | 更新日期: 2023-09-27 18:35:35

我有一些代码充当轻量级、非阻塞的关键部分。我希望无论Task.Run子句中的_funccancellationToken发生什么情况,都可以保证延续运行,以便其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();
            }
        })
}

继续保证执行

基于 MSDN 文档:

返回的任务不会计划执行,直到当前任务完成,无论是由于成功完成而完成,由于未处理的异常而出错,还是由于被取消而提前退出。

因此,除非_func永远不会返回(例如在无限循环中运行),否则延续将始终运行。

当延续运行时,最终块保证按照 C# 的规则执行。

所以答案是肯定的(当然,除非_func永远不会回来)。

如果在第一个任务运行之前取消令牌,则不会运行延续,因此 finally 将不会执行。 此处使用 VS 2015 进行测试:http://pastebin.com/9qmUYnqv

顺便说一下,编写的代码存在一些设计问题 - 让任务修改状态不是最好的主意;任务应该返回值等等。 在这种特殊情况下,对于非阻塞关键部分,请考虑使用 SemaphoreSlim。