【问题标题】:Restart the internal cancellation timer of the Windows.Web.Http.HttpClient on progress event重新启动 Windows.Web.Http.HttpClient on progress 事件的内部取消计时器
【发布时间】:2018-05-04 07:50:58
【问题描述】:
    using (var httpClient = new HttpClient(filter))
    {
      using (var httpContent = new HttpStringContent(postBody, UnicodeEncoding.Utf8, content_type))
      {
        var source = new CancellationTokenSource(150000);
        HttpResponseMessage result;
        try
        {
          result = await httpClient.PostAsync(new Uri(url), httpContent).AsTask(source.Token, new Progress<HttpProgress>(
            progress =>
          {
            Debug.WriteLine("Progress");
          }));
        }
        catch (TaskCanceledException e)
        {
          return new ServerRequestResponse(RequestResponseType.Timeout);
        }
        catch (Exception e)
        {
          return new ServerRequestResponse(RequestResponseType.Failure);
        }

        var buffer = await result.Content.ReadAsBufferAsync();
        var byteArray = buffer.ToArray();
        var responseString = Encoding.UTF8.GetString(byteArray, 0, byteArray.Length);
        return new ServerRequestResponse(RequestResponseType.Success, responseString);
      }
    }

上面的代码调用一个帖子到服务器并且有一个超时。我需要做的是在收到 Progress 调用后重新启动内部超时计数器。我需要它来检测传输是否仍在进行或已停止,因为有时在慢速连接上它可能会比超时持续时间更长。

是否有这样的功能,或者我需要实现自己的计时器才能手动重新启动它?

【问题讨论】:

    标签: c# uwp timeout httprequest cancellationtokensource


    【解决方案1】:

    我需要这个来检测转移是否仍在进行

    您无法检测到传输是否仍在进行,IAsyncOperationWithProgress 接口仅提供Progress 事件处理程序。你可以检测到进度Stage

    httpResponse = await httpClient.GetAsync(requestUri).AsTask(source.Token, new Progress<HttpProgress>((Progress) =>
    {
        Debug.WriteLine(Progress.BytesReceived.ToString() + "---" + Progress.Stage);
    }));
    

    但是,您无法从输出中识别出已完成的进度。

    0------SendingHeaders
    0------WaitingForResponse
    0------ReceivingHeaders
    0------ReceivingContent
    65536------ReceivingContent
    98304------ReceivingContent
    98432------ReceivingContent
    98432------ReceivingContent
    

    您只能从HttpStatusCode 检测到完成的进度。

    我需要做的是在收到 Progress 调用后重新启动内部超时计数器。

    httpclient 中默认的timeout 值是 100,000 毫秒(100 秒)。 如果请求数据超过 100 秒,则需要手动设置超时时间。

    var cts = new CancellationTokenSource();
    
    ......
    
    cts.CancelAfter(2000);
    

    【讨论】:

    • 我将此标记为答案,因为它包含许多有用的数据。我使用用于“超时”的自定义计时器解决了我的问题。每次抛出 Progress 事件时我都会重置计时器,因此我能够大致检测到传输的空闲时间。这对我的目的来说已经足够了。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-10-02
    • 2017-08-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多