2017-10-11 37 views
0

タイムアウトを増やしましたが、TaskCanceledExceptionを取得しています。驚くべきことに、常に発生することさえありません。例外はいつか発生するだけで、エラーを再現するパターンを見つけることができません。私はネットワークコールを行うために使用している例外トレースとコードを追加しました。HttpClient c# - SendASyncでタスクがキャンセルされました

Exception Trace Image

public static void getResponseFromUrlAsync<T>(T payload, string url, 
    Action<string> onSuccess, Action<string> onFailure) 
{ 
    string contentType = "application/json"; 
    httpClient = new HttpClient(); 
    httpClient.Timeout = TimeSpan.FromMinutes(30); 
    HttpRequestMessage requestMsg = new HttpRequestMessage(); 
    requestMsg.RequestUri = new Uri(NetworkCallUrls.baseUri + url); 
    Utils.debugLog("Url", NetworkCallUrls.baseUri + url); 

    // try 
    //{ 
    string auth = "Bearer " + Objects.GlobalVars.GetValue<string>("access_token"); // //"x1VwaR1otS66ZCTlgtv3X9aaSNpDOn"; // 
    httpClient.DefaultRequestHeaders.Add("Authorization", auth); 
    requestMsg.Method = HttpMethod.Post; 

    requestMsg.Content = new StringContent(
        Utils.stringifyData(payload), 
        Encoding.UTF8, 
        contentType); 

    httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));//ACCEPT header 

    makeNetworkCallCheckResponseStatusAndExecuteCorrospondingAction(requestMsg, onSuccess, onFailure, progressBarStatus); 
} 

internal static void disposeConnection(HttpClient httpClient) 
{ 
    httpClient.Dispose(); 
    httpClient = null; 
} 

private static async void makeNetworkCallCheckResponseStatusAndExecuteCorrospondingAction(
    HttpRequestMessage requestMsg, Action<string> onSuccess, 
    Action<string> onFailure, Action<bool> progressBarStatus) 
{ 
    Utils.debugLog("IN MAKE NETWORK CALL 1"); 
    HttpResponseMessage response = await httpClient.SendAsync(requestMsg); 
    Utils.debugLog("IN MAKE NETWORK CALL 2"); 
    ResponseStatus responseStatus = checkResponseStatusAndExecuteActionAccordinglyAsync(response); 
    Utils.debugLog("IN MAKE NETWORK CALL 3"); 
    if (responseStatus.isSuccess) 
    { 
     Utils.debugLog("IN MAKE NETWORK CALL 4"); 
     string responseString = await response.Content.ReadAsStringAsync(); 
     Utils.debugLog("IN MAKE NETWORK CALL 5"); 
     onSuccess(responseString); 
     Utils.debugLog("IN MAKE NETWORK CALL 6"); 
    } 
    else 
    { 
     Utils.debugLog("IN MAKE NETWORK CALL 7"); 
     onFailure(responseStatus.failureResponse); 
     Utils.debugLog("IN MAKE NETWORK CALL 8"); 
    } 
    Utils.debugLog("IN MAKE NETWORK CALL 9"); 
    disposeConnection(httpClient); 
    Utils.debugLog("IN MAKE NETWORK CALL 10"); 
} 

私はHttpResponseMessage response = await httpClient.SendAsync(requestMsg);ラインでTaskCanceledExceptionを取得しています、API呼び出しを行うために上記のコードを使用しています。

私はこの問題を解決するのに役立つかもしれません。私はインターネットで検索し、タイムアウトを増やすだけでなく使用します。私はあなたの問題を解決するのに役立つことを願っています

答えて

1

makeNetworkCallCheckResponseStatusAndExecuteCorrospondingActionメソッドとgetResponseFromUrlAsyncメソッドの両方を待機する必要があります。

public static async Task getResponseFromUrlAsync<T>(T payload, string url, Action<string> onSuccess, Action<string> onFailure) 
{ 
    string contentType = "application/json"; 
    httpClient = new HttpClient(); 
    httpClient.Timeout = TimeSpan.FromMinutes(30); 
    HttpRequestMessage requestMsg = new HttpRequestMessage(); 
    requestMsg.RequestUri = new Uri(NetworkCallUrls.baseUri + url); 
    Utils.debugLog("Url", NetworkCallUrls.baseUri + url); 


    string auth = "Bearer " + Objects.GlobalVars.GetValue<string>("access_token"); // //"x1VwaR1otS66ZCTlgtv3X9aaSNpDOn"; // 
    httpClient.DefaultRequestHeaders.Add("Authorization", auth); 
    requestMsg.Method = HttpMethod.Post; 

    requestMsg.Content = new StringContent(
        Utils.stringifyData(payload), 
        Encoding.UTF8, 
        contentType); 

    httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));//ACCEPT header 

    await makeNetworkCallCheckResponseStatusAndExecuteCorrospondingAction(requestMsg, onSuccess, onFailure, progressBarStatus) 
     .ConfigureAwait(false); 
} 

internal static void disposeConnection(HttpClient httpClient) 
{ 
    httpClient.Dispose(); 
    httpClient = null; 
} 

private static async Task makeNetworkCallCheckResponseStatusAndExecuteCorrospondingAction(
    HttpRequestMessage requestMsg, Action<string> onSuccess, 
    Action<string> onFailure, Action<bool> progressBarStatus) 
{ 
    Utils.debugLog("IN MAKE NETWORK CALL 1"); 
    HttpResponseMessage response = await httpClient.SendAsync(requestMsg).ConfigureAwait(false); 
    Utils.debugLog("IN MAKE NETWORK CALL 2"); 
    ResponseStatus responseStatus = checkResponseStatusAndExecuteActionAccordinglyAsync(response); 
    Utils.debugLog("IN MAKE NETWORK CALL 3"); 
    if (responseStatus.isSuccess) 
    { 
     Utils.debugLog("IN MAKE NETWORK CALL 4"); 
     string responseString = await response.Content.ReadAsStringAsync().ConfigureAwait(false); 
     Utils.debugLog("IN MAKE NETWORK CALL 5"); 
     onSuccess(responseString); 
     Utils.debugLog("IN MAKE NETWORK CALL 6"); 
    } 
    else 
    { 
     Utils.debugLog("IN MAKE NETWORK CALL 7"); 
     onFailure(responseStatus.failureResponse); 
     Utils.debugLog("IN MAKE NETWORK CALL 8"); 
    } 
    Utils.debugLog("IN MAKE NETWORK CALL 9"); 
    disposeConnection(httpClient); 
    Utils.debugLog("IN MAKE NETWORK CALL 10"); 
} 

...とawaitあなたはそれを呼び出す方法:これは、あなたがTaskvoidから戻り値の型を変更する必要があることを意味第二のために

await getResponseFromUrlAsync<..>(...); 
+0

私には問題があると思います.APIのcall_1が完了する前に、httpClientが新しいもので更新されていますので、前回の呼び出しが返される前に、何度も何度も複数の呼び出しを行うので、別の呼び出しをしています。 – djkp

+0

しかし、最高のプラクティスに従って、コードを更新します:) – djkp

+0

それはあなたがメソッドを待つ必要がある理由です。 – mm8

2

いくつかのコメント:あなたは、voidを返していないことは何もない場合

  1. async方法はTaskを返す必要があります。 Taskオブジェクトを実際に返す必要はなく、コンパイラがこれを処理します。唯一の例外はWinFormsとWebFormsのイベントハンドラです。
  2. getResponseFromUrlAsyncのメソッドは非同期ではありませんが、それはそうでなければなりません。 async修飾子を追加し、Taskを返す必要があります。次に、await makeNetworkCallCheckResponseStatusAndExecuteCorrospondingAction(...)。これは問題の原因となる可能性があります。非同期操作が完了するまで待ってから戻ってください。
  3. 一般的に、httpClient変数はどこかでグローバルに定義されているようです。 makeNetworkCallCheckResponseStatusAndExecuteCorrospondingActionは、getResponseFromUrlAsyncを最初に呼び出さなくても呼び出すことができるので、NullReferenceExceptionを簡単に実行できます。disposeConnectionも可能です。クラスが常にhttpClientを使用する場合は、コンストラクタまたは宣言で初期化します。そうでない場合は、メソッドの開始時にnullでないことを確認します。
+0

、私は「makeNetworkCallCheckResponseStatusAndExecuteCorrospondingAction」に待っていますだから、私は待っていると非同期とタスクは 'getResponseFromUrlAsync'の返信として必要ないと思った – djkp

+0

@ djkp、あなたはそうです。 'makeNetworkCallCheckResponseStatusAndExecuteCorrospondingAction'は非同期で、あなたがそれを待たずに実行を終了する前に戻ります。 asyncで始めると、ルートをプログラムするために非同期で実行されます。 –

関連する問題