获取异步HttpWebRequest的响应

我想知道是否有一个简单的方法来获得异步httpwebrequest的响应。

我已经在这里看到了这个问题但是我想要做的就是将字符串forms的响应(通常是json或xml)返回到另一个方法,然后我可以解析它/相应地处理它。

下面是一些代码:

我在这里有这两个静态方法,我认为这些方法是线程安全的,因为所有的参数都被传入并且方法没有共享的局部变量?

public static void 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; request.BeginGetResponse(new AsyncCallback(ReadCallback), request); } private static void ReadCallback(IAsyncResult asyncResult) { HttpWebRequest request = (HttpWebRequest)asyncResult.AsyncState; try { using (HttpWebResponse response = (HttpWebResponse)request.EndGetResponse(asyncResult)) { Stream responseStream = response.GetResponseStream(); using (StreamReader sr = new StreamReader(responseStream)) { //Need to return this response string strContent = sr.ReadToEnd(); } } manualResetEvent.Set(); } catch (Exception ex) { throw ex; } } 

假设问题是您很难获得返回的内容,最简单的路径可能是使用async / await,如果您可以使用它。 如果您使用的是.NET 4.5,那么更好的方法是切换到HttpClient,因为它本身就是“异步”。

使用.NET 4和C#4,您仍然可以使用Task来包装这些并使其更容易访问最终结果。 例如,下面是一个选项。 请注意,在内容字符串可用之前,它会使Main方法阻塞,但在“真实”场景中,您可能会将任务传递给其他内容,或者将其他ContinueWith串起来或其他任何内容。

 void Main() { var task = MakeAsyncRequest("http://www.google.com", "text/html"); Console.WriteLine ("Got response of {0}", task.Result); } // Define other methods and classes here public static Task 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 task = Task.Factory.FromAsync( request.BeginGetResponse, asyncResult => request.EndGetResponse(asyncResult), (object)null); return task.ContinueWith(t => ReadStreamFromResponse(t.Result)); } private static 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; } } 

“如果你使用的是.NET 4.5,那么更好的方法就是切换到HttpClient,因为它本身就是’async’。” – 詹姆斯曼宁绝对正确的答案。 大约2年前就提出了这个问题。 现在我们有.NET framework 4.5,它提供了强大的异步方法。 使用HttpClient。 请考虑以下代码:

  async Task HttpGetAsync(string URI) { try { HttpClient hc = new HttpClient(); Task result = hc.GetStreamAsync(URI); Stream vs = await result; StreamReader am = new StreamReader(vs); return await am.ReadToEndAsync(); } catch (WebException ex) { switch (ex.Status) { case WebExceptionStatus.NameResolutionFailure: MessageBox.Show("domain_not_found", "ERROR", MessageBoxButtons.OK, MessageBoxIcon.Error); break; //Catch other exceptions here } } } 

要使用HttpGetAsync(),请创建一个“异步”的新方法。 async是必需的,因为我们需要在GetWebPage()方法中使用“await”:

 async void GetWebPage(string URI) { string html = await HttpGetAsync(URI); //Do other operations with html code } 

现在,如果您想异步获取网页html源代码,只需调用GetWebPage(“web-address …”)。 甚至Stream读取也是异步的。

注意:要使用HttpClient,.NET Framework 4.5是必需的。 您还需要在项目中添加System.Net.Http引用,并添加“ using System.Net.Http ”以便于访问。

有关此方法的工作原理,请访问: http : //msdn.microsoft.com/en-us/library/hh191443(v = vs.110).aspx

使用Async: 4.5中的异步:值得等待

一旦你去异步,你永远不会回去。 从那里你只能真正访问async的回调。 你可以提高这个的复杂性并做一些线程和等待,但这可能是一个痛苦的努力。

从技术上讲,您还可以在需要等待结果时暂停线程,但我不建议您,此时您也可以执行正常的http请求。

在C#5中,它们具有异步/等待命令,这将使得更容易获得对主线程的异步调用的结果。

 public static async Task GetBytesAsync(string url) { var request = (HttpWebRequest)WebRequest.Create(url); using (var response = await request.GetResponseAsync()) using (var content = new MemoryStream()) using (var responseStream = response.GetResponseStream()) { await responseStream.CopyToAsync(content); return content.ToArray(); } } public static async Task GetStringAsync(string url) { var bytes = await GetBytesAsync(url); return Encoding.UTF8.GetString(bytes, 0, bytes.Length); }