Task方法返回TaskCanceledException被捕获

时间:2014-08-09 17:54:04

标签: c# wpf async-await

我正在尝试调用服务,该服务应该返回所有记录,但我得到一个TaskCancelledException,其中包含一条消息A Task被取消,然后结果为null。我知道有很多数据(尝试使用小数据并且工作正常)。我怎样才能让它继续工作(继续抓取记录)而不抛出" A任务被取消"。这是我的方法

public async Task<ActionResult<string>> ObtainData(string url, CancellationToken ct = default(CancellationToken))
{            
    Result<string> result = new Result<string>();
    try
    {
        HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Get, url);
        HttpResponseMessage response = await httpClient.SendAsync(request); //HttpClient

        string jsonresult = await HandleReceipt(response, type);

        result.Result = jsonresult;
    }
    catch (Exception ex)
    {
        result.Message = "Problem obtaining data.";
    }

    return result;
}

我看到有一个取消令牌被传递,有没有办法处理取消?此外,从这里调用此方法:

public async void GetJsonData()
{
    string json = await ObtainData();
}

我希望它能在不取消的情况下完成请求。

2 个答案:

答案 0 :(得分:2)

从您的问题和评论中可以看出您的请求已超时。尝试设置HttpClient.Timeout属性

public async Task<ActionResult<string>> ObtainData(string url, CancellationToken ct = default(CancellationToken))
{            
   Result<string> result = new Result<string>();
   try
   {
       var request = (HttpWebRequest) WebRequest.Create(url);
       request.Method = "GET";
       HttpResponseMessage response = await httpClient.SendAsync(request); //HttpClient
       httpClient.TimeOut = TimeSpan.MaxValue // change this as you like

       string jsonresult = await HandleReceipt(response, type);

       result.Result = jsonresult;
   } 
   catch (Exception ex)
   {
      result.Message = "Problem obtaining data.";
   }

   return result;
}

修改

关于您对异常的评论,这是来自MSDN:

  

必须在调用GetRequestStream或GetResponse方法之前设置Timeout属性。

在发出请求之前创建HttpClient的新实例,或者在初始化客户端的代码中设置它(构造函数我假设)。

答案 1 :(得分:1)

正如Yuval Itzchakov所提到的,你应该将Timeout属性设置为更大的值(但它是TimeSpan不是整数),如果你使用异步模式,你应该在HTTP请求调用中使用取消令牌。 而且没有必要使用全局HttpClient(正如Yuval指出的那样),特别是在这个重度异步方法中调用噩梦(另外我没有看到为什么应该在ObtainData内部调用异步的原因)。

    public async Task<ActionResult<string>> ObtainData(string url, CancellationToken ct = default(CancellationToken))
    {
        try
        {
            using (var httpClient = new HttpClient
            {
                Timeout = TimeSpan.MaxValue
            })
            {
                using (var request = new HttpRequestMessage(HttpMethod.Get, url))
                {
                    using (var response = await httpClient.SendAsync(request, ct))
                    {
                        return new ActionResult<string>()
                        {
                            Result = await HandleReceipt(response, type)
                        };
                    }
                }
            }
        }
        catch (Exception ex)
        {
            return new ActionResult<string>
            {
                Message = "Problem obtaining data. " + ex
            };
        }
    }