0

このコードを使用して、低速のインターネット接続に遭遇しないようにするために行っている要求呼び出しに 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

4

1 に答える 1

2

CancellationTokenタイムアウト(new CancellationTokenSource(myTimeSpan).Token)を使用することをお勧めします。これは、メソッド内で使用できますasync(たとえば、HttpClientトークンをGetAsyncメソッドに渡します)。HTTPリクエスト自体がキャンセルされるため、これにより消費されるリソースが少なくなります。

ただし、「外部」タイムアウトが必要な場合は、より自然なアプローチは次のようになります。

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)

于 2013-03-04T13:10:28.393 に答える