前言:本人最近较多使用.net core的项目,最近在使用httpClient发送请求的时候,遇到服务器处理时间较长时,就老是会报异常:TaskCanceledException: A task was canceled。 我的使用异步请求的方法也较为老套,使用的Task a=()=>{}; a.Wait(); 来等待异步操作的结束,这种方式执行等待时,就常会出现上面的异常信息,在.net Core中httpClient添加配置超时时长也没用:
services.AddHttpClient("PPHttpClient", config => { config.DefaultRequestHeaders.Add("Accept", "*/*"); config.DefaultRequestHeaders.Add("AcceptLanguage", "en-US"); config.Timeout = TimeSpan.FromMinutes(5); config.DefaultRequestHeaders.Add("Accept-Encoding", "gzip, deflate"); });
但是程序在运行中,时不时给你来个异常,也让人受不了! 后来也尝试过使用异常捕获,然后再次请求的方案,这种方案治标不治本,有时候标也治不了,就一直给你抛取消异常,你就一直捕获不断重试去吧,程序会卡在那里!!
后来就各种百度啊,终于在一篇文章中找到了解决方案,使用 async+await的方案替代task.Wait()是个好的解决方案,至于为什么? 本人真心不知道,只了解到task.Wait()是一种比较老的写法,而async+await是目前主流的异步处理方案,可能优化了各种问题吧,反正好用哈。。。 这是在百度里找到的文章:https://cloud.tencent.com/developer/ask/176717
其实针对异步请求处理的方案,我的博客里原来的一篇转发文章也提到了该方案,只不过自己忘记看了,真是一有问题就找百度,忘了自己还有一套百宝箱呢!!哈哈....
使用Task异步执行方法_多线程_应用程序池
划重点:0x05 使用async/await进行异步操作
这个是C#5中的新特性,当遇到await时,会从线程池中取出一个线程异步执行await等待的操作,然后方法立即返回。等异步操作结束后回到await所在的地方接着往后执行。await需要等待async Task<T>类型的函数。详细的使用方法可参考相关资料,测试代码如下所示。异步结束后的会返回到调用线程,所以修改UI不需要Dispatcher。
也可以把TestTask包装成async方法,这样就可以使用上图中注释掉的两行代码进行处理。包装后的异步方法如下所示:
async/await也是从线程池中取线程,可实现线程复用,而且代码简洁容易阅读,异步操作返回后会自动返回调用线程,是执行异步操作的首选方式。而且虽然是C#5的新特性,但C#4可以通过下载升级包来支持async/await。
.Net core webapi使用httpClient发送异步请求遇到TaskCanceledException: A task was canceled