C# 如何使HttpWebRequest异步

C# 如何使HttpWebRequest异步,c#,httpwebrequest,.net-4.5,C#,Httpwebrequest,.net 4.5,我有这样的代码: private async Task<string> Request(url) { Task<string> task = null; try { task = MakeAsyncRequest(url, "text/html"); return await task; } catch {

我有这样的代码:

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;
        }
    }
但是由于某种原因,代码堆积在
return wait task.ContinueWith(t=>ReadStreamFromResponse(t.Result))和冻结

有没有更好的方法,或者有人可以解释发生了什么? 正如我在博客上解释的那样,我没有收到任何错误,只是等待的
有点问题。

。总之,
await
将捕获一个“上下文”(例如,UI上下文),并使用它来恢复
async
方法。某些上下文(例如UI上下文)只允许上下文中有一个线程。因此,如果通过调用
Result
来阻止该特殊线程(例如UI线程),则
async
方法无法在该上下文中恢复执行

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

foreach(var url in myUrlList)
{
  string body = await ProcessAsync(method);
}
其他说明:

任务返回方法应以“Async”结尾,以遵循

Task.Factory.fromsync
是不必要的
HttpWebRequest
已经有了等待的方法。更好的选择是使用
HttpClient

我建议您不要使用
Task.ContinueWith
(或
Task.Result
,或
Task.Wait
);改用
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);
}
私有异步任务MakeAsyncRequestAsync(字符串url,字符串contentType)
{
HttpWebRequest请求=(HttpWebRequest)WebRequest.Create(url);
request.ContentType=ContentType;
request.Method=WebRequestMethods.Http.Get;
请求超时=20000;
Proxy=null;
WebResponse=wait request.GetResponseAsync();
返回ReadStreamFromResponse(response);
}

如果您将
HttpWebRequest
更改为
HttpClient

刚刚编辑:
string body=Process(method).Result=>
字符串体=请求(方法)。结果
我是否应该更改方法
请求(…)
?是的,但核心问题仍然是
结果
调用。您应该使用
wait
而不是
Result
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);
}