gpt4 book ai didi

c# - 如何使 HttpWebRequest 异步

转载 作者:行者123 更新时间:2023-11-30 13:57:16 28 4
gpt4 key购买 nike

我有这样的代码:

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

但由于某种原因,代码在 return await task.ContinueWith(t => ReadStreamFromResponse(t.Result)); 处堆积,然后就卡住了。

有没有更好的方法可以做到这一点,或者有人可以解释发生了什么?我没有收到任何错误,只是 await 有问题....

最佳答案

call to Result in your foreach loop is causing a deadlock ,正如我在我的博客上解释的那样。总之,await 将捕获“上下文”(例如,UI 上下文),并使用它来恢复 async 方法。一些上下文(例如,UI 上下文)只允许上下文中有一个线程。因此,如果您通过调用 Result 阻塞该特殊线程(例如,UI 线程),则 async 方法无法在该上下文中恢复执行。

因此,解决方案是更改您的 foreach 循环:

foreach(var url in myUrlList)
{
string body = await ProcessAsync(method);
}

其他说明:

任务返回方法应以“Async”结尾以遵循 TAP guidelines .

Task.Factory.FromAsync 是不必要的; HttpWebRequest 已经有可等待的方法。一个更好的选择是改用 HttpClient

我建议你不要使用Task.ContinueWith(或Task.Result,或Task.Wait);请改用 await

有了这些简化:

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,则可以进一步简化此代码。

关于c# - 如何使 HttpWebRequest 异步,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22171928/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com