代码之家  ›  专栏  ›  技术社区  ›  djkpA

HttpClient c#-在SendASync上取消了任务

  •  1
  • djkpA  · 技术社区  · 7 年前

    TaskCanceledException 即使我增加超时。令人惊讶的是,它甚至不总是发生,异常只在某个时候发生,我无法找到模式来重现错误。我添加了异常跟踪和用于进行网络调用的代码。

    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");
    }
    

    我正在使用上述代码进行API调用,我正在获取TaskCanceledException HttpResponseMessage response = await httpClient.SendAsync(requestMsg); 线

    有人能帮我解决这个问题吗。我在网上搜索,也增加了超时时间,但没有用。

    2 回复  |  直到 7 年前
        1
  •  2
  •   Tsahi Asher    7 年前

    我希望一些评论能帮助您解决问题:

    1. async 方法应返回 Task 如果你没有东西要还,不要 void 任务 对象,编译器将处理此问题。唯一的例外是WinForms和WebForms事件处理程序。
    2. 你的 getResponseFromUrlAsync 方法不是异步的,但它应该是异步的。您应该添加一个 异步 修饰符,并返回 . 然后 await makeNetworkCallCheckResponseStatusAndExecuteCorrospondingAction(...) . 这可能是问题的根源-您没有等待异步操作在返回之前完成。
    3. 总的来说,你的 httpClient makeNetworkCallCheckResponseStatusAndExecuteCorrospondingAction 即使不呼叫也可以呼叫 getResponseFromUrlAsync 首先,我们也可以 disposeConnection . 如果您的类始终使用 httpClient
        2
  •  1
  •   mm8    7 年前

    你应该等待 makeNetworkCallCheckResponseStatusAndExecuteCorrospondingAction 方法和 getResponseFromUrlAsync 方法这意味着您需要将返回类型从 void Task :

    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 调用时的方法:

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