【问题标题】:Task inlining and Task.Wait任务内联和 Task.Wait
【发布时间】:2012-03-24 21:18:46
【问题描述】:

我刚刚意识到,当我从一个任务中启动一个任务并调用 Task.Wait 时,新任务将不会被内联,而调用 Task.Result 将始终内联任务。

当我们使用 RAII 模式(在 ExecuteWithCancel 中实现)包装我们的任务时,内联将重用分配的资源并且是可取的。

但我们有时想等待一段时间并在此之后取消任务。 等待代码如下:

using (var cts = new CancellationTokenSource())
{
   // Task scheduler decides whether to execute synchronous or asynchronous
   var task = new Task<TResult>(() => ExecuteWithCancel<TResult>(cts.Token, nameOfTaskPerformer, arguments), cts.Token)
   if (timeout==TimeSpan.Zero || task.Wait(timeout)) // this creates an all or nothing timeout
      return task.Result;
   cts.Cancel();
   throw new TimeoutException("");
}

当超时为TimeSpan.Zero时,任务被内联,否则它总是使用另一个线程。

是否有一种简单的方法可以重新设计此代码以使用内联和等待/超时?

【问题讨论】:

标签: c# .net task-parallel-library


【解决方案1】:

很确定这是不可能的。假设您在线程 A 上运行以下代码:

var task = Task.Factory.StartNew(() => Thread.Sleep(Timeout.Infinite));
task.Wait(5000);

如果任务是内联的,线程 A 将无限期阻塞 - 超时后它将如何唤醒? 查看参考源(Task.cs),我们可以确切地看到:

internal bool InternalWait(int millisecondsTimeout, CancellationToken cancellationToken) 
{
   ...
   // we will attempt inline execution only if an infinite wait was requested 
   // Inline execution doesn't make sense for finite timeouts and if a cancellation token was specified
   // because we don't know how long the task delegate will take. 
   if (millisecondsTimeout == Timeout.Infinite && !cancellationToken.CanBeCanceled &&
       WrappedTryRunInline() && IsCompleted) 
   {
       returnValue = true; 
   } 
   else
   { 
       returnValue = CompletedEvent.Wait(millisecondsTimeout, cancellationToken);
   }

根据您的问题,为了从有限超时内联中受益,您必须在任务本身内部实现超时逻辑,可能类似于:

ExecuteWithCancel<TResult>(cts.Token, TimeSpan timeout, nameOfTaskPerformer, arguments)

然后使用普通的Wait()(或Result)。

【讨论】:

  • 伟大的思想都一样;)下次您可以回答自己的问题,以便其他人能够从您找到的解决方案中受益
  • 嗯,我在这里有一个答案解释了为什么不能内联任务,我围绕这个建立了一个解决方案。但是答案在我接受之前就被删除了。所以这个问题被遗忘了......
  • 好吧,我没有9次无缘无故收到死灵法师徽章;)
猜你喜欢
  • 2023-03-10
  • 2015-02-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-09-25
  • 1970-01-01
  • 1970-01-01
  • 2014-02-27
相关资源
最近更新 更多