2016-10-08 2 views
1

HttpClient.PostAsyncを使用して、応答を返送するための人為的な時間があるURLにHTTP要求を投稿する方法を教えてください。人工タイムアウト後にURLが応答するときにHttpClient.PostAsyncを非同期で使用する方法?

URLとパラメータsleep = 30に注意してください。これは、HTTP応答を返す前に30秒の人為的な遅延を導入するために使用されます。

 Console.WriteLine("Start time : " + DateTime.Now); 

     for (int i = 1; i <= 10; i++) 
     { 
      using (var client = new HttpClient()) 
      { 
       client.BaseAddress = new Uri(@"http://fake-response.appspot.com/api/?data={Hello World}&sleep=30"); 
       //client.BaseAddress = new Uri(@"http://fake-response.appspot.com/api/?data={Hello World}&status=200"); 

       client.Timeout = new TimeSpan(0, 0, 60); 

       var parameters = new Dictionary<string, string>(); 
       parameters["ContentType"] = "text/plain;charset=UTF-8"; 

       //Create Task to POST to the URL 
       client.DefaultRequestHeaders.ExpectContinue = true; 
       var response = await client.PostAsync(client.BaseAddress, new FormUrlEncodedContent(parameters)); 

       Task<bool> b1 = ProcessURLAsync(response, 1, 5, 2); 
      } 
     } 

     Console.WriteLine("End time : " + DateTime.Now); 

何行われる必要があることは、非同期HTTPの投稿がループ内で行われる必要があり、URLで指定されたタイムアウトに依存すべきではないということです。 ただし、PostAsyncは応答を受信する前にタイムアウトします。

10件の非同期の記事

のループで2つの異なるURLを投稿するために必要な時間を確認してください、私はHttpClient.DefaultRequestHeaders.ExpectContinueを確認し、私はこれは、このユースケースに役立つかもしれないと思います。

+0

わかりませんが、無限のタイムアウトが必要なのでしょうか? –

+0

@KooKiz - それは代案ですが、要求が非同期になることはありません –

+0

要求は30秒かかると予想されますが、タイムアウトは10秒に設定され、タイムアウトします。ここで何が間違っていますか? – Evk

答えて

2

このような人為的な遅延は、クライアントの観点から見ると、ネットワークタイムアウトと変わりありません。したがって、client.Timeoutを予想される最大人工遅延+実際のネットワークタイムアウト時間に設定する必要があります。 await PostAsyncから返されたタスク。応答待ちをブロックしたくない場合。あなたはそのようなすべてのタスクをいくつかのリストに保存して、すべてがawait Task.WhenAll(yourTaskList)で完了するのを待つことができます。または、与えられたタスクが完了すると、ContinueWithを使用して特定のアクションを実行できます。しかし、もしあなたが応答を気にしていれば、とにかく十分なタイムアウトを設定しなければなりません。さもなければ、要求は途中で中止されます。ここで

は、応答が受信される前に、しかしPostAsync時間を

static async void MakeRequests() 
    { 
     var requests = new List<Task<bool>>(); 
     for (int i = 1; i <= 10; i++) 
     { 
      // no await here, so, not await MakeRequest(i); 
      requests.Add(MakeRequest(i)); 
     } 
     // now all 10 requests are running in parallel 
     try { 
      await Task.WhenAll(requests); 
     } 
     catch { 
      // no need to handle it here - we handle all errors below 
     } 

     // if we are here, all requests are either completed or failed, inspect their results 
     foreach (var request in requests) { 
      if (request.IsCanceled) { 
       // failed by timeout 
      } 
      else if (request.IsFaulted) { 
       // failed 
       Log(request.Exception); 
      } 
      else { 
       // success 
       bool result = request.Result; 
       // handle your result here if needed 
      } 
     } 
    } 

    static async Task<bool> MakeRequest(int i) { 
     using (var client = new HttpClient()) { 
      client.BaseAddress = new Uri(@"http://fake-response.appspot.com/api/?data={Hello World}&sleep=30"); 
      //client.BaseAddress = new Uri(@"http://fake-response.appspot.com/api/?data={Hello World}&status=200"); 
      // no timeout here, or set to max expected delay 
      //client.Timeout = new TimeSpan(0, 0, 60); 

      var parameters = new Dictionary<string, string>(); 
      parameters["ContentType"] = "text/plain;charset=UTF-8"; 

      //Create Task to POST to the URL 
      client.DefaultRequestHeaders.ExpectContinue = true; 
      var response = await client.PostAsync(client.BaseAddress, new FormUrlEncodedContent(parameters)); 

      Task<bool> b1 = ProcessURLAsync(response, 1, 5, 2); 
      return b1; 
     } 
    } 
+0

応答を処理する必要があります。 基本的には、単一の応答(またはすべての応答の合計時間)を待つか、どちらも問題を解決しません(非同期要求のPOST - 人為的な応答時間)。これで問題は解決しませんが、これは答えに近いと思いますが、それ以上のインプットを待っています。 –

+0

私はあなたが必要とするものを本当に理解していません。あなたはいくつかのリクエストを並行して行い(**タスクを待っていない**)、すべてのレスポンスのうちの何回かを待つのではなく、それらのレスポンスの_max_回を待つ(並行して実行されるため)。 ContinueWith(待たずに)を使用して、各応答をすぐに処理したい場合は、そのまま使用してください。 – Evk

+0

質問のソースコードを編集しました。 \t \t \tこの使用例を理解する最も良い方法は、上記のサンプルコードで2つの異なるURLに対して10回のPOSTを実行するのにかかる時間を確認することです。 asyncが使用されていても、URLに擬似時間遅延が含まれている場合、POSTに必要な時間に大きな時間差があります。 –

1

をあなたを助けるためにいくつかのサンプルコードです。

このメソッドは、HttpClient.Timeoutプロパティを10秒に設定しているためタイムアウトします。このプロパティを設定すると、応答が受信されない場合、指定された時間後にクライアントにタイムアウトするように指示されます。

+0

タイムアウトを設定しない場合、デフォルトは100秒、人為的な遅延が100秒を超えるとタイムアウトになります。 タイムアウトに関係なく、処理がラインで停止します。 var response = await client .PostAsync(client.BaseAddress、新しいFormUrlEncodedContent(parameters)); さらに移動するのではなく、要求からの応答を待機します。 URLから –

+0

人為的な遅延(スリープ= 30)を削除すると、この待機は発生しません。もう1人のユーザーがあなたの質問に既に回答しています:1)HttpClientで設定したタイムアウトを増やす必要があります。 2)PostAsyncの後に待機する必要はありませんが、PostAsyncの呼び出しから返されたすべてのタスクをリストに集めてから、Task.WhenAll(tasks)を待つように呼び出してください。 – oldbam

+0

はい –

関連する問題