任务中的代码如何知道它已超时?

时间:2011-11-29 18:34:05

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

请考虑以下代码:

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");
  }
}

3 个答案:

答案 0 :(得分:2)

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

Joe Hoad在Parallel FX Team blog处提供了一个实现此功能的实现,并涵盖了一些人们可能容易忽略的边缘情况。

答案 1 :(得分:1)

在这种情况下,你不会。

如果您希望能够杀死未及时返回的任务,则需要将取消令牌传递给异步调用(而不是在该方法中创建),这样您就可以发出信号取消来自您的来电者(在这种情况下为主)。

答案 2 :(得分:0)

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

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