2015-01-02 27 views
5

私は簡単な方法で取得し、投稿実行するHttp Web Requestクラスのラッパーを開発した.NET HTTP要求タイムアウトは、連続的なストリーミングサイト上で「中止」ではない

範囲。このライブラリはすでに2年以上問題なく使用されていますが、今日は奇妙な問題に直面しました。

one website(ロードに時間がかかります)は、明らかにHTMLフロントエンドにストリーミング文字を保持しているので、私たちのライブラリ「Get」リクエストはループに巻き込まれます。我々は二つの異なるtimeout性質があることを見つけるのHttp Webリクエストの参照を見てみると

異なるタイムアウトプロパティ

。私たちは両方を使用していますが、どれも適切に中断していないようです。

  • Read Write Timeout - ストリームへの書き込みまたはストリームからの読み取りのタイムアウトをミリ秒単位で取得または設定します。
  • Timeout - GetResponseおよびGetRequestStreamメソッドのタイムアウト値をミリ秒単位で取得または設定します。

つのタイムアウトは、それらを支配するために、すべての

いくつかの事前設定した時間後に廃棄ストリーム/接続を強制的に「操作タイムアウト」を設定する方法はありますか?

いくつかのコードサンプル

public class Program 
{ 
public static void Main() 
{ 
    string url = "http://anus.io"; 

    Console.WriteLine("Initializing Request State Object"); 

    RequestState myRequestState = new RequestState(); 

    // Creating Http Request 
    myRequestState.request = (HttpWebRequest)WebRequest.Create(url); 
    myRequestState.request.Method   = "GET"; 
    myRequestState.request.ReadWriteTimeout = 4000; 
    myRequestState.request.Timeout   = 4000; 

    Console.WriteLine("Begining Async Request"); 


    IAsyncResult ar = myRequestState.request.BeginGetResponse(new AsyncCallback(ResponseCallback), myRequestState); 

    Console.WriteLine("Waiting for Results"); 
    ar.AsyncWaitHandle.WaitOne(); 

    myRequestState.response = (HttpWebResponse)myRequestState.request.EndGetResponse(ar); 
    Console.WriteLine("Response status code = {0}", myRequestState.response.StatusCode); 

} 

public static void ResponseCallback (IAsyncResult asyncResult) 
{ 
    Console.WriteLine("Completed"); 
} 
} 

This Code seem to work fineが、それは常にtransmitedされているので、(ブラウザが示すように)どのように私は、文字列として応答を読んでいますか?

質問

このようなウェブサイトを処理するための適切な方法は何ですか? (?ハンドルによって私は、サーバーは、単に送信を止めるつもりはないような状況を識別し、スキップできるようにする意味)

答えて

1

これを試してみてください:

public static void Main() 
{ 

    string url = "http://anus.io"; 

    ***int DefaultTimeOut = 15000;*** //timeout after 15 sec 

    Console.WriteLine("Initializing Request State Object"); 

    RequestState myRequestState = new RequestState(); 

    // Creating Http Request 
    myRequestState.request = (HttpWebRequest)WebRequest.Create(url); 
    myRequestState.request.Method   = "GET"; 
    myRequestState.request.ReadWriteTimeout = 4000; 
    myRequestState.request.Timeout   = 4000; 

    Console.WriteLine("Begining Async Request"); 


    IAsyncResult ar = myRequestState.request.BeginGetResponse(new AsyncCallback(ResponseCallback), myRequestState); 

    ***ThreadPool.RegisterWaitForSingleObject(ar.AsyncWaitHandle, new WaitOrTimerCallback(TimeoutCallback), myRequestState.request, DefaultTimeOut, true);*** 

    Console.WriteLine("Waiting for Results"); 
    ar.AsyncWaitHandle.WaitOne(); 

    try{ 

    myRequestState.response = (HttpWebResponse)myRequestState.request.EndGetResponse(ar); 
    Console.WriteLine("Response status code = {0}", myRequestState.response.StatusCode); 
    }catch(Exception){ 
     Console.WriteLine("Request Aborted"); 
    } 
} 

public static void ResponseCallback (IAsyncResult asyncResult) 
{ 
    Console.WriteLine("Completed"); 
} 

//call the timeout if more than 15 seconds 

**public static void TimeoutCallback(object state, bool timedOut) 
{ 
      if (timedOut) 
      { 
       HttpWebRequest request = state as HttpWebRequest; 
       if (request != null) 
       { 
        request.Abort(); 
       } 
      } 
}** 
0

私はTaskと利用されるように全体のHTTP処理を移動しますそのタスクにタイムアウトを設定する一般的な手法です。多くのそのような技術が利用可能である。

私はあなたが非常に多くの個別のタイムアウトを必要とする理由はわかりません。あなたはちょうど言うことができません:この要求が4秒以上かかる場合は、理由を問わず、それを殺す。

APMパターンとイベントの待機は、.NET 4.5とC#5の時代には赤いフラグです。その迷惑メールはすべてあなたのコードの意図を覆い隠します。 awaitを使用してWebRequestクラスが提供するasync IOを使用し、その周りにラップされた汎用タイムアウト手法を使用すると、ジャンクはなくなります。

関連する問題