Webrequestのtimeout属性の作用範囲

3326 ワード

c#を使用してWebページ情報をキャプチャする場合、httpwebrequestを使用してキャプチャする場合、通常はtimeoutタイムアウト値をカスタマイズします.設定しないと、システムのデフォルトのタイムアウト値が高くなり、長時間待つ意味がないことが多いので、手動で5秒などの小さな値を設定するほうがいいです.このように5秒以内に接続できない場合は、接続を再確立したり、他のことをしたりすることが考えられます.
しかし、使用中に奇妙な現象が発見されたのは、1つのページのキャプチャが設定されたtimeout値を超えており、異常もデータのキャプチャも完了していないため、非常に長い時間待ってからエラーを報告する必要があるということです.よく調べたTimeoutの説明:
Timeoutは、後続の同期要求時にGetResponseメソッドを使用して応答を待機し、GetRequestStreamメソッドを使用してストリームを待機するミリ秒数です.Timeoutは、GetRequestStreamおよびGetResponseメソッドに対して単独で応答を呼び出さないリクエストおよび応答全体に適用されます.リソースがタイムアウト期間内に戻る場合、要求はWebExceptionを開始し、Status属性をWebExceptionStatusに設定.Timeout.Timeoutプロパティは、GetRequestStreamメソッドまたはGetResponseメソッドが呼び出される前に設定する必要があります.GetRequestStreamメソッドまたはGetResponseメソッドを呼び出した後にTimeoutプロパティを変更しても機能しません.Timeoutプロパティは、BeginGetResponseメソッドまたはBeginGetRequestStreamメソッドを使用して生成された非同期リクエストに対して無効です.
timeoutの役割ドメインは、ターゲットサーバとの接続を確立するタイムアウト時間を制御することであると考えられます.すなわち、サーバと所定のtimeout時間内にtcp接続を確立できれば、異常はありません.その後、ページデータのダウンロードが遅いプロセスはtimeoutの範囲内ではありません.これにより、ダウンロードプロセスが長くなり、結果が得られなくなります.この推測を検証するために、私はいくつかのページを作って、それぞれ中にSystemを設定しました.Threading.Thread.Sleep(n)法は人為的に遅延する.
まず、キャプチャされたコードです.
HttpWebRequest req =(HttpWebRequest)  WebRequest.Create("http://lixin.me/t1");
            req.Timeout = 5000; //       5 
            Stopwatch timer = new Stopwatch();
            timer.Start();
            HttpWebResponse resp = (HttpWebResponse)req.GetResponse();
            StreamReader reader = new StreamReader(resp.GetResponseStream());
            string data = reader.ReadToEnd();
            timer.Stop();
            textBox1.AppendText(data + "\r
"+timer.Elapsed.TotalSeconds.ToString()+"\r
");

このうち、「t 1」、「t 2」、「t 3」、「t 4」のいくつかのページを作成しました.
ここで、t 1ページはテキスト内容を直接返し、ベース対照として使用する.
t 2ページには遅延が設定されているが、遅延時間はタイムアウトの範囲内である.
t 3ページには遅延が設定されているが、遅延時間はキャプチャプログラムのtimeout時間を超えている.
t 4ページはまずクライアントに一部のコンテンツを送信し,timeoutよりも長い時間遅延し,ネットワーク速度が遅い様子をシミュレートし,残りの文字列を送信した.
コードは次のとおりです.
public ActionResult t1()
        {
            return Content("      。");
        }
        public ActionResult t2()
        {
            System.Threading.Thread.Sleep(3000);
            return Content("   3 ");
        }
        public ActionResult t3()
        {
            System.Threading.Thread.Sleep(7000);
            return Content("   7 ");
        }
        public ActionResult t4()
        {
            //      ,       t4.aspx   ,  asp.net mvc
            Response.Write("hello");
            Response.Flush();
            System.Threading.Thread.Sleep(8000);
            return Content(" lixin");
        }

テストの結果は次のとおりです.
t 1はすぐにコンテンツを返し、エラーはありません.
t 2は3秒後にも内容を返し、エラーはなかった.
t 3は、5秒後にクライアントがtimeoutのエラーを投げ出す.
t 4は8秒後にコンテンツを返し、エラーは発生しなかった.
テストの結果、timeoutが設定した時間には、データのダウンロードにかかる時間は含まれません.
では、所定の時間内にデータのダウンロードタスクを完了しないと再開されますか?これはHttpwebRequestのもう一つの属性値を使用しなければなりません:ReadWriteTimeout
ReadWriteTimeoutプロパティは、GetRequestStreamメソッドによって返されるストリームを書き込むとき、またはGetResponseStreamメソッドによって返されるストリームを読み込むときに使用されます.具体的には、ReadWriteTimeoutプロパティは、GetResponseStreamメソッドによって返されるストリームを読み取るReadメソッドと、GetRequestStreamメソッドによって返されるストリームを書き込むWriteメソッドのタイムアウトを制御する.リクエストの完了待ち時間を指定するには、Timeoutプロパティを使用します.
このプロパティの設定は、ドキュメントの説明に従って、データストリームの読み出しのタイムアウト時間を設定します.