2011-09-10 5 views
5

私は、非同期HTTP要求を作成するためのコードのこの部分を持っている:タスクfromAsyncタイムアウト

public static void MakeRequest(Uri uri, Action<RequestCallbackState> responseCallback) 
    { 
     WebRequest request = WebRequest.Create(uri); 
     request.Proxy = null; 

     Task.Factory.FromAsync<WebResponse>(request.BeginGetResponse, request.EndGetResponse, null).ContinueWith(task => 
      { 
       WebResponse response = task.Result; 
       Stream responseStream = response.GetResponseStream(); 
       responseCallback(new RequestCallbackState(response.GetResponseStream())); 
       responseStream.Close(); 
       response.Close(); 
      }); 
    } 

それは動作しますが、私は、要求タイムアウトを設定する必要があります。私はrequest.Timeoutを使用しようとしましたが、何もしていないようです。このコードでタスクのタイムアウトを設定する方法はありますか?

新しいタイムアウトコールバックを追加するように編集しました。 新しいコード:

public static void MakeRequest(Uri uri, Action<RequestCallbackState> responseCallback) 
    { 
     WebRequest request = WebRequest.Create(uri); 
     request.Proxy = null; 

     IAsyncResult t = Task.Factory.FromAsync<WebResponse>(request.BeginGetResponse, request.EndGetResponse, null).ContinueWith(task => 
      { 
       WebResponse response = task.Result; 
       Stream responseStream = response.GetResponseStream(); 
       responseCallback(new RequestCallbackState(response.GetResponseStream())); 
       responseStream.Close(); 
       response.Close(); 
      }); 
     ThreadPool.RegisterWaitForSingleObject(t.AsyncWaitHandle, new WaitOrTimerCallback(TimeoutCallback), request, 1000, true); 
    } 

    private static void TimeoutCallback(object state, bool timedOut) 
    { 
     if (timedOut) 
     { 
      Console.WriteLine("Timeout"); 
      WebRequest request = (WebRequest)state; 
      if (state != null) 
      { 
       request.Abort(); 
      } 
     } 
    } 

テストで:

HttpSocket.MakeRequest(new Uri("http://www.google.comhklhlñ"), callbackState => 
    { 
     if (callbackState.Exception != null) 
      throw callbackState.Exception; 
     Console.WriteLine(GetResponseText(callbackState.ResponseStream)); 
    }); 
Thread.Sleep(10000); 

答えて

8

Timeout documentationから:

TimeoutプロパティはBeginGetResponseまたはBeginGetRequestStream方法で作られた非同期要求には影響しません。

これは、フレームワークがあなた自身でタイムアウトを処理するためです。 example code hereを使用することができますが、ThreadPool.RegisterWaitForSingleObjectメソッドへのFromAsyncコールから返されたTaskが返されます。


編集:あなたは元のタスクではなく、継続に登録を置くために

必要があります。

public static void MakeRequest(Uri uri, Action<Stream> responseCallback) 
{ 
    WebRequest request = WebRequest.Create(uri); 
    request.Proxy = null; 
    const int TimeoutPeriod = 1000; 

    Task<WebResponse> t = Task.Factory.FromAsync<WebResponse>(request.BeginGetResponse, request.EndGetResponse, null); 
    ThreadPool.RegisterWaitForSingleObject((t as IAsyncResult).AsyncWaitHandle, TimeoutCallback, request, TimeoutPeriod, true); 
    t.ContinueWith(task => 
    { 
     WebResponse response = task.Result; 
     Stream responseStream = response.GetResponseStream(); 
     responseCallback(response.GetResponseStream()); 
     responseStream.Close(); 
     response.Close(); 
    }); 
} 

これは私の作品(私は非常に短いタイムアウト時間を設定した場合、およびこれを打つ、私はいつも適切にタイムアウトする)。

+0

質問でわかるようにコードを変更しましたが、タイムアウトが機能していません。私はtimedOut falseでコールバックを受信し、その後は何も起こりません。 –

+0

@David:私はいくつかの作業コードを入れました... –

+0

私はそれを動作させることはできません。私はメインメソッドにthread.sleepを持っています。これが問題だろうか?私はあなたがそれをテストするために使用しているコードを表示するために投稿を更新しました。 –

関連する問題