を継承する独自のクラスを作成することです。 HttpWebRequest.Timeout
およびHttpWebRequest.ReadWriteTimeout
。 の両方をとする必要があります。
HttpWebRequest.ReadWriteTimeout
まずは、HttpWebRequest.ReadWriteTimeout
に対処しましょう。 「ストリームバッファリングを無効にする」必要があります。この設定で
httpRequest.AllowWriteStreamBuffering = false;
あなたは、あなたが(5分)既定値でそれらを残したり、それらを減らすことができますし、それらを希望としてあなたHttpWebRequest.ReadWriteTimeout
値が魔法のように動作しますが、変更しました。私は60秒を使う。
この問題は、大きなファイルをアップロードするときに、.NETフレームワークによってデータがバッファされている場合、コードがアップロードが完了していないと判断し、HttpWebRequest.GetResponse()
を呼び出す時間が早すぎるために発生します。
HttpWebRequest.Timeout
さて、HttpWebRequest.Timeout
に対処しましょう。
HttpWebRequest.Timeout
がアップロード全体に適用されるため、2番目の問題が発生します。 開始アップロードに
- 要求:アップロード・プロセスは、実際には3つのステップ(here's a great article that was my primary reference)から構成されています。
- バイトの書き込み。
- へのリクエストアップロードとサーバーからの応答を取得します。
アップロード全体に適用されるタイムアウトが1つの場合は、大きなファイルをアップロードするために大きな番号が必要ですが、タイムアウトが実際にタイムアウトするまでに時間がかかるという問題もあります。これは良い状況ではありません。代わりに、ステップ#1とステップ#3に適用するために短い時間(例えば30秒)が必要です。私たちは#2で全面的なタイムアウトを望んでいませんが、一定の期間バイトが書き込まれなくなると、アップロードが失敗することがあります。ありがたいことに、我々は既にHttpWebRequest.ReadWriteTimeout
で#2を扱っていますが、ちょうどHttpWebRequest.Timeout
の厄介な振る舞いを修正する必要があります。 GetRequestStream
とGetResponse
の非同期バージョンは、われわれが必要としているものとまったく同じものであることが判明しました。
ですから、このコードをしたい:
public static class AsyncExtensions
{
public static Task<T> WithTimeout<T>(this Task<T> task, TimeSpan timeout)
{
return Task.Factory.StartNew(() =>
{
var b = task.Wait((int)timeout.TotalMilliseconds);
if (b) return task.Result;
throw new WebException("The operation has timed out", WebExceptionStatus.Timeout);
});
}
}
、代わりのGetRequestStream
とGetResponse
を呼び出して、我々は非同期バージョンを呼び出します:応答のための
var uploadStream = httpRequest.GetRequestStreamAsync().WithTimeout(TimeSpan.FromSeconds(30)).Result;
と同様:
var response = (HttpWebResponse)httpRequest.GetResponseAsync().WithTimeout(TimeSpan.FromSeconds(30)).Result;
を
これですべてが必要です。今あなたのアップロードははるかに信頼性が高くなります。追加の確実性のために、アップロード全体を再試行ループでラップするかもしれません。
ありがとうございます。しかし、私はまだそれがどのように役立つのか分かりません。今のところ、.NET CLRには、HttpWebRequest.ReadWriteTimeoutとStreamを作るhttp://stackoverflow.com/questions/2679192/httpwebrequest-readwritetimeout-ignored-in-net-works-in-monoのバグがあるようです。 WriteTimeoutは役に立たない。あなたのソリューションはこれをどのように克服するのに役立ちますか? – Alex
マネージャーC#では、これらのプロパティにアクセスすることはできません。 MyRequestを使用して、コードをクラスに追加します。それほど難しくありません。 – jdweng
私はHttpWebRequest.Timeoutを設定することができます。子孫クラスで同じプロパティを直接設定する目的は何ですか?効果はどのように違うでしょうか? – Alex