c# – 如何使HttpWebRequest异步
发布时间:2020-12-16 02:00:27 所属栏目:百科 来源:网络整理
导读:我有这样的代码: private async Taskstring Request(url) { Taskstring task = null; try { task = MakeAsyncRequest(url,"text/html"); return await task; } catch { return null; } } private async Taskstring MakeAsyncRequest(string url,string cont
我有这样的代码:
private async Task<string> Request(url) { Task<string> task = null; try { task = MakeAsyncRequest(url,"text/html"); return await task; } catch { return null; } } private async Task<string> MakeAsyncRequest(string url,string contentType) { HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url); request.ContentType = contentType; request.Method = WebRequestMethods.Http.Get; request.Timeout = 20000; request.Proxy = null; Task<WebResponse> task = Task.Factory.FromAsync( request.BeginGetResponse,asyncResult => request.EndGetResponse(asyncResult),(object)null); //issue here: return await task.ContinueWith(t => ReadStreamFromResponse(t.Result)); } private string ReadStreamFromResponse(WebResponse response) { using (Stream responseStream = response.GetResponseStream()) using (StreamReader sr = new StreamReader(responseStream)) { //Need to return this response string strContent = sr.ReadToEnd(); return strContent; } } 我在foreach循环中调用Request(url) foreach(var url in myUrlList) { string body = Request(method).Result; } 但由于某种原因,代码在返回时堆叠等待task.ContinueWith(t => ReadStreamFromResponse(t.Result));只是冷冻. 有没有更好的方法来做到这一点,或者有人可以解释发生了什么? 解决方法
call to
Result in your foreach loop is causing a deadlock,正如我在博客上解释的那样.总之,await将捕获“上下文”(例如,UI上下文),并使用它来恢复异步方法.一些上下文(例如,UI上下文)仅允许上下文中的一个线程.因此,如果通过调用Result来阻止该特殊线程(例如,UI线程),则异步方法无法在该上下文中继续执行.
所以,解决方案是改变你的foreach循环: foreach(var url in myUrlList) { string body = await ProcessAsync(method); } 其他说明: 任务返回方法应以“异步”结束,以遵循TAP guidelines. Task.Factory.FromAsync是不必要的; HttpWebRequest已经有了等待的方法.更好的选择是使用HttpClient. 我建议你不要使用Task.ContinueWith(或Task.Result,或Task.Wait);请改用. 通过这些简化: private async Task<string> MakeAsyncRequestAsync(string url,string contentType) { HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url); request.ContentType = contentType; request.Method = WebRequestMethods.Http.Get; request.Timeout = 20000; request.Proxy = null; WebResponse response = await request.GetResponseAsync(); return ReadStreamFromResponse(response); } 如果将HttpWebRequest更改为HttpClient,则可以进一步简化此代码. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |