C# 获取异步 HttpWebRequest 的响应
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/10565090/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Getting the Response of a Asynchronous HttpWebRequest
提问by gdp
Im wondering if theres an easy way to get the response of an async httpwebrequest.
我想知道是否有一种简单的方法来获取异步 httpwebrequest 的响应。
I have already seen this question herebut all im trying to do is return the response (which is usually json or xml) in the form of a string to another method where i can then parse it/ deal with it accordingly.
我已经在这里看到了这个问题,但我想要做的就是以字符串的形式将响应(通常是 json 或 xml)返回到另一种方法,然后我可以相应地解析它/处理它。
Heres some code:
继承人一些代码:
I have these two static methods here which i think are thread safe as all the params are passed in and there are no shared local variables that the methods use?
我这里有这两个静态方法,我认为它们是线程安全的,因为所有参数都被传入并且没有这些方法使用的共享局部变量?
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;
}
}
采纳答案by James Manning
Assuming the problem is that you're having a hard time getting to the returned content, the easiest path would likely be using async/await if you can use it. Even better would be to switch to HttpClient if you're using .NET 4.5 since it's 'natively' async.
假设问题是您很难访问返回的内容,那么最简单的路径可能是使用 async/await(如果可以的话)。如果您使用的是 .NET 4.5,则最好切换到 HttpClient,因为它是“本机”异步的。
Using .NET 4 and C# 4, you can still use Task to wrap these and make it a bit easier to access the eventual result. For instance, one option would be the below. Note that it has the Main method blocking until the content string is available, but in a 'real' scenario you'd likely pass the task to something else or string another ContinueWith off of it or whatever.
使用 .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<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);
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;
}
}
回答by Thinking Sites
Once you go async, you can never go back. From there you only really have access to the async's callback. you can ramp up the complexity of this and do some threading & waithandles but that can be rather a painful endeavor.
一旦你去异步,你就再也回不去了。从那里你只能真正访问异步的回调。您可以增加它的复杂性并进行一些线程处理和等待处理,但这可能是一项相当痛苦的工作。
Technically, you can also sleep the thread when you need to wait for the results, but I don't recommend that, you may as well do a normal http request at that point.
从技术上讲,您也可以在需要等待结果时使线程休眠,但我不建议这样做,此时您也可以执行正常的 http 请求。
In C# 5 theyhave async/await commands that will make it easier to get the results of the async call to the main thread.
在 C# 5 中,它们具有 async/await 命令,可以更轻松地获取对主线程的异步调用的结果。
回答by mirushaki
"Even better would be to switch to HttpClient if you're using .NET 4.5 since it's 'natively' async." - absolutely right answer by James Manning. This question was asked about 2 years ago. Now we have .NET framework 4.5, whic provides powerful asynchronous methods. Use HttpClient. Consider the following code:
“如果您使用的是 .NET 4.5,那么最好切换到 HttpClient,因为它是‘本机’异步的。” - 詹姆斯曼宁绝对正确的答案。这个问题是大约 2 年前提出的。现在我们有了 .NET framework 4.5,它提供了强大的异步方法。使用 HttpClient。考虑以下代码:
async Task<string> HttpGetAsync(string URI)
{
try
{
HttpClient hc = new HttpClient();
Task<Stream> 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
}
}
}
To use HttpGetAsync(), make a new method that is "async" too. async is required, because we need to use "await" in GetWebPage() method:
要使用 HttpGetAsync(),也要创建一个“异步”的新方法。async 是必需的,因为我们需要在 GetWebPage() 方法中使用“await”:
async void GetWebPage(string URI)
{
string html = await HttpGetAsync(URI);
//Do other operations with html code
}
Now if you want to get web-page html source code asynchronously, just call GetWebPage("web-address..."). Even Stream reading is asynchronous.
现在,如果您想异步获取网页 html 源代码,只需调用 GetWebPage("web-address...")。甚至 Stream 读取也是异步的。
NOTE: to use HttpClient .NET framework 4.5 is required. Also you need to add System.Net.Httpreference in your project and add also "using System.Net.Http" for easy access.
注意:要使用 HttpClient .NET 框架 4.5 是必需的。您还需要System.Net.Http在项目中添加引用并添加“ using System.Net.Http”以便于访问。
For further reading how this approach works, visit: http://msdn.microsoft.com/en-us/library/hh191443(v=vs.110).aspx
如需进一步阅读此方法的工作原理,请访问:http: //msdn.microsoft.com/en-us/library/hh191443(v=vs.110).aspx
Use of Async: Async in 4.5: Worth the Await
回答by dragansr
public static async Task<byte[]> 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<string> GetStringAsync(string url) {
var bytes = await GetBytesAsync(url);
return Encoding.UTF8.GetString(bytes, 0, bytes.Length);
}

