【问题标题】:How can code within a Task know that it has timed out?Task 中的代码如何知道它已超时?
【发布时间】:2012-01-09 02:15:24
【问题描述】:

考虑以下代码:

public class EventManager
{
  public Task<string> GetResponseAsync(string request)
  {
    CancellationTokenSource tokenSource = new CancellationTokenSource();

    return new Task<string>( () =>
    {
      // send the request
      this.Send(request);

      // wait for the response until I've been cancelled or I timed out.
      // this is important because I want to cancel my "wait" if either occur

      // WHAT CODE CAN I WRITE HERE TO SEE IF THIS TASK HAS TIMED OUT?
      // (see the example below)
      // 
      // Note that I'm not talking about cancellation
      // (tokenSource.Token.IsCancellationRequested)

      return response;
    }, tokenSource.Token);
  }
}


public static void Main()
{
  EventManager mgr = new EventManager();
  Task<string> responseTask = mgr.GetResponseAsync("ping");
  responseTask.Start();

  if (responseTask.Wait(2000))
  {
    Console.WriteLine("Got response: " + responseTask.Result);
  }
  else
  {
    Console.WriteLine("Didn't get a response in time");
  }
}

【问题讨论】:

    标签: .net asynchronous timeout task-parallel-library


    【解决方案1】:

    任务不包括开箱即用的超时功能。您可以通过启动一个 Timer 来添加它,如果它尚未完成,它将在超时后取消任务。

    Joe Hoad 在Parallel FX Team blog 上提供了一个实现,它可以做到这一点,并涵盖了几个很容易忽略的边缘情况。

    【讨论】:

      【解决方案2】:

      在这种情况下,你不会。

      如果您希望能够终止未及时返回的任务,则需要将取消令牌传递给异步调用(而不是在该方法中创建它),以便您可以发出信号通知它从您的呼叫者取消(在本例中为 Main)。

      【讨论】:

      • 很抱歉我不能也将你标记为答案,但我至少赞成你的答案。
      【解决方案3】:

      您无法知道您的Task 是否超时,因为在此示例中它实际上从未超时。 Wait API 将在 Task 完成或指定时间过去时阻塞。如果时间过去了,Task 本身没有任何反应,Wait 的调用者只会返回 false。 Task 继续保持不变

      如果您想与Task 交流您不再对其结果感兴趣,最好的方法是使用取消。

      【讨论】:

      • 这就是我担心的答案。 “任务继续运行不变”。我不希望发生这种情况,也不想强制客户端在超时时必须手动取消任务。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-07-17
      • 1970-01-01
      • 2020-01-29
      • 2016-10-12
      相关资源
      最近更新 更多