Pergunta

Using ASP.Net WebAPI, I have a controller with an asynchronous action similar to the following:

[HttpPost]
public async Task<string> DoSomething(string foo)
{
  var result = await MyAsynchronousTask(foo);
  return result;
}

What this controller does is unimportant. Whats important is that it is awaiting an asynchronous task using the new .net 4.5 async/await support.

Question: How do I tell it to time out after a specified duration? I don't necessarily want to cancel the task, I just want to prevent the caller from hanging on forever. (Although, I would be interested in seeing it both ways.)

Foi útil?

Solução

I made a version in LINQPad with the 'C# Program' selection - it compiles and runs with output of 2 lines, showing both the time-out and success cases:

Timeout of 00:00:05 expired

Successfully got result of foo

Here's the snippet:

void Main()
{
    CallGetStringWithTimeout(TimeSpan.FromSeconds(5), TimeSpan.FromSeconds(10)).Wait();
    CallGetStringWithTimeout(TimeSpan.FromSeconds(5), TimeSpan.FromSeconds(0)).Wait();
}

public async Task CallGetStringWithTimeout(TimeSpan callTimeout, TimeSpan callAddedDelay)
{
    var myTask = GetStringAsync(callAddedDelay);
    await Task.WhenAny(Task.Delay(callTimeout), myTask);
    if (myTask.Status == TaskStatus.RanToCompletion)
    {
        Console.WriteLine ("Successfully got result of {0}", await myTask);
    }
    else
    {
        Console.WriteLine ("Timeout of {0} expired", callTimeout);
    }
}

public async Task<string> GetStringAsync(TimeSpan addedDelay)
{
    await Task.Delay(addedDelay);
    return "foo";
}

However, the 'normal' way is using CancellationTokenSource and specifying your timeout as the ctor param. If you already have a CancellationTokenSource, you can call the CancelAfter method on it, which will schedule the cancellation for the specified timeout.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top