Получение ответа асинхронного запроса HttpWebRequest
Мне интересно, есть ли простой способ получить ответ async httpwebrequest.
Я уже видел этот вопрос здесь, но все, что я пытаюсь сделать, это вернуть ответ (обычно это 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;
}
}
Ответы
Ответ 1
Предполагая, что проблема заключается в том, что вам трудно добраться до возвращаемого содержимого, самый простой путь, скорее всего, будет использовать async/await, если вы сможете его использовать. Еще лучше было бы переключиться на HttpClient, если вы используете .NET 4.5, поскольку он "изначально" async.
Используя .NET 4 и С# 4, вы все равно можете использовать Task для их переноса и упростить доступ к конечным результатам. Например, один из вариантов будет ниже. Обратите внимание, что он блокирует основной метод до тех пор, пока строка содержимого не будет доступна, но в "реальном" сценарии вы, скорее всего, передадите задачу на что-то другое или добавите строку 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;
}
}
Ответ 2
"Еще лучше было бы переключиться на HttpClient, если вы используете .NET 4.5, так как это" асинхронно ". - абсолютно правильный ответ Джеймса Мэннинга.
Этот вопрос задавали около 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
}
}
}
Чтобы использовать HttpGetAsync(), создайте новый метод, который также является "асинхронным". async требуется, потому что нам нужно использовать "ожидание" в методе 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
Использование Async: Async в 4.5: стоит Await
Ответ 3
Как только вы перейдете на асинхронный режим, вы никогда не сможете вернуться назад. Оттуда у вас действительно есть доступ к асинхронному обратному вызову. вы можете увеличить сложность этого и сделать некоторые потоки и waithandles, но это может быть довольно болезненным делом.
Технически вы также можете спятить поток, когда вам нужно ждать результатов, но я не рекомендую это делать, вы можете также выполнить обычный HTTP-запрос в этой точке.
В С# 5 у них есть команды async/await, которые облегчат получение результатов асинхронного вызова в основной поток.