雖然你可以依靠WithCancellation
再利用的目的,超時簡單的解決方案(不扔OperationCanceledException
)是創建一個超時任務與Task.Delay
,等待第一個任務使用Task.WhenAny
完成:
public static Task<TResult> WithTimeout<TResult>(this Task<TResult> task, TimeSpan timeout)
{
var timeoutTask = Task.Delay(timeout).ContinueWith(_ => default(TResult), TaskContinuationOptions.ExecuteSynchronously);
return Task.WhenAny(task, timeoutTask).Unwrap();
}
或者,如果您想在發生超時而不是僅僅返回默認值的情況下拋出異常(即, null
):
public static async Task<TResult> WithTimeout<TResult>(this Task<TResult> task, TimeSpan timeout)
{
if (task == await Task.WhenAny(task, Task.Delay(timeout)))
{
return await task;
}
throw new TimeoutException();
}
而且用法是:
var content = await Response.Content.ReadAsStringAsync().WithTimeout(TimeSpan.FromSeconds(1));
僅供參考,如果你處理的IDisposable的超時你可能想看看這個:[異步網絡運營寫不完](HTTP ://stackoverflow.com/a/21468138/885318) – i3arnon 2014-09-23 06:09:07