我想知道,如果那里有一个简单的方法来获得一个异步HttpWebRequest的响应。
我已经看到了这个问题在这里 ,但所有我尝试做的是返回响应(通常是JSON或XML)将字符串中的另一种方法,我可以再分析它/它相应的处理形式。
下面有一些代码:
我已经为所有的PARAMS在过去,有没有共享的局部变量的方法使用该在这里我认为这两个静态方法是线程安全的吗?
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;
}
}
假设的问题是,你有一个很难得到返回的内容,最简单的路径很可能是使用异步/等待,如果你可以使用它。 更妙的是,如果你使用.NET 4.5,因为它的“原生地”异步切换到HttpClient的。
使用.NET 4和C#4,你仍然可以用任务来包装这些并使其更容易一点进入最终的结果。 例如,其中一个方案是下面。 需要注意的是它具有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;
}
}
“更妙的是切换到HttpClient的,如果你正在使用.NET 4.5,因为它是‘原生’异步”。 - 由詹姆斯·曼宁绝对正确的答案。 这个问题大约2年前有人问。 现在我们有.NET框架4.5,whic提供了强大的异步方法。 使用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
}
}
}
要使用HttpGetAsync(),使一个新的方法,那就是“异步”了。 异步是必需的,因为我们需要使用GetWebPage“等待”()方法:
async void GetWebPage(string URI)
{
string html = await HttpGetAsync(URI);
//Do other operations with html code
}
现在,如果你想获得异步网页的HTML源代码,只需拨打GetWebPage(“网络地址...”)。 即使流阅读是异步的。
注意:要使用的HttpClient的.NET framework 4.5是必需的。 你也需要添加System.Net.Http
在您的项目引用,并添加也“ using System.Net.Http
”为方便。
进一步阅读这种方法是如何工作的,请访问: http://msdn.microsoft.com/en-us/library/hh191443(v=vs.110).aspx
:使用异步的4.5异步:值得等待
一旦你去异步,你永远不能回去。 从那里,你才真正有机会获得异步的回调。 你可以斜升的这种复杂性,并做一些线程与waithandles但可以是相当痛苦的努力。
从技术上讲,你也可以睡线程,当你需要等待结果,但我不建议,你不妨做在这一点上正常的http请求。
在C#全心全意5异步/等待命令,这将使它更容易得到异步调用的结果主线程。
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);
}