是任务.延迟值得取消

本文关键字:取消 值得 延迟 任务 | 更新日期: 2023-09-27 18:11:22

我最近使用我在很多地方看到的取消模式重新实现了一大堆异步 WCF 服务方法 - 您等待启动任务和 Task.Delay 的Task.WhenAny。当然,现有任务是不可取消的,但希望在以后的版本中解决。

就我而言,Task.Delay的默认持续时间由服务设置控制。 在绝大多数情况下,结果是期望的任务在必要的时间内完成。设置通常变得大方。

我看到的大多数(但不是全部(示例都懒得取消Task.Delay。是不是这么便宜,不值得担心?我知道取消会引发例外。 如果我取消延迟,我应该处理异常吗?

这是我所做的所有服务方法都通过它调用的方法:

private async Task<T> GetOrTimeout<T>( Task<T> task, [CallerMemberName] string caller = "" )
{
  using ( var cts = new CancellationTokenSource( ) )
  {
    try
    {
      var timeout = GetDelay( cts.Token );
      var first = await Task.WhenAny( task, timeout );
      if ( first == timeout ) throw new TimeoutException( Properties.Resources.TimeoutOccurredInService.Fmt( caller ) );
      cts.Cancel( );  //--> haven't been doing this. Should I?
      return await task;
    }
    catch ( Exception ex )
    {
      throw LoggedFaultException( ex, caller );
    }
  }
}

。创建延迟的方法如下所示:

private Task GetDelay( CancellationToken token )
{
  return Task
    .Delay( Properties.Settings.Default.ServiceMethodTimeout, token )
    .ContinueWith( _ => { }, TaskContinuationOptions.ExecuteSynchronously );
}

如果我不取消延迟,我保留资源的时间是否超过必要的时间?特别是,我担心 WCF 启动以调用服务方法的实例。我担心他们会削减配置服务的并发参数。超时设置非常粗糙。不取消似乎很浪费,但这对我来说都是很新的东西。

由于

取消涉及异常,并且由于我被训练为不使用异常来传达状态,这感觉就像我把自己描绘成一些我不完全理解的可怕的反模式。也许Task.Delay对我来说不是正确的选择。感觉我让它变得比我应该的更复杂。如能说明情况,将不胜感激。

是任务.延迟值得取消

首先,这整个问题在性能方面可能可以忽略不计,只有在真实环境中进行测试后才应考虑。

但是,如果我们深入研究,Task.Delay创建一个在一定间隔后完成的任务。它通过创建一个新的System.Threading.Timer(实现IDisposable(来实现,该使用ThreadPool线程在间隔后完成承诺任务。

如果你"经常"使用Task.Delay,你可能会有相当多的浪费资源在它们有用之后很长一段时间内徘徊。如果您还使用捕获任何引用的委托向Task.Delay任务添加任何延续,它们也将无缘无故地闲逛。

所以,是的,取消任务比让它用完更安全,尽管可能不是很多。

当您

关心应用程序的关机速度时,Task.Delay值得取消。

一个例子是 asp.net Web 应用程序。

当服务器回收您的Web应用程序时(例如,当它正在实时更新时(,它需要快速结束一切。如果您有任务在后台等待,尤其是通过QueueBackgroundObject或类似技术注册的任务,则应用程序可能需要一段时间才能关闭。