我正在使用这段代码将TimeOut附加到我正在进行的请求调用中,以确保我们不会遇到缓慢的互联网连接 - 并且处理得当。 当我满足超时条件时,我收到一条错误消息,我无法在扩展功能中修复。
如何一般地完成这项任务?
代码:
public static class SOExtensions
{
public static Task<T> WithTimeout<T>(this Task<T> task, TimeSpan duration)
{
return Task.Factory.StartNew(() =>
{
bool b = task.Wait(duration);
if (b) return task.Result;
return default(T);
});
}
}
用法:
var response = await HttpWebRequest
.Create(request)
.GetResponseAsync()
.WithTimeout(TimeSpan.FromSeconds(1));
我使用此处理AggregateException
(并通过WebException
),但在超时失败时仍会生成AggregateException
。
答案 0 :(得分:2)
我建议您使用CancellationToken
超时(new CancellationTokenSource(myTimeSpan).Token
),然后您可以在 async
方法中使用(例如HttpClient
,您将令牌传递给GetAsync
方法。这会占用更少的资源,因为HTTP请求本身已被取消。
但如果你想要一个&#34;外部&#34;超时,更自然的方法是:
public static async Task<T> WithTimeout<T>(this Task<T> task, TimeSpan duration)
{
var timeout = Task.Delay(duration);
var completeTask = await Task.WhenAny(task, timeout);
if (completeTask == timeout)
return default(T);
else
return await task;
}
这可以防止异常被包装到AggregateException
中。但它不如CancellationToken
方法有效,它看起来像这样:
var timeout = new CancellationTokenSource(TimeSpan.FromSeconds(1));
var response = await new HttpClient().GetAsync(uri, timeout.Token);
请注意,如果超时,CancellationToken
方法将抛出OperationCanceledException
而不是返回default(T)
。