Как я могу использовать HttpWebRequest (.NET, C#) асинхронно?Как использовать HttpWebRequest (.NET) асинхронно?
ответ
Применение HttpWebRequest.BeginGetResponse()
HttpWebRequest webRequest;
void StartWebRequest()
{
webRequest.BeginGetResponse(new AsyncCallback(FinishWebRequest), null);
}
void FinishWebRequest(IAsyncResult result)
{
webRequest.EndGetResponse(result);
}
Функция обратного вызова вызывается при завершении асинхронной операции. Вам нужно как минимум позвонить EndGetResponse()
с этой функции.
BeginGetResponse не так полезен для использования async. Кажется, он блокируется при попытке связаться с ресурсом. Попробуйте отключить сетевой кабель или дать ему неправильный uri, а затем запустить этот код. Вместо этого вам, вероятно, нужно запустить GetResponse во втором потоке, который вы предоставляете. – Ash 2012-10-21 03:52:46
@AshleyHenderson - Не могли бы вы предоставить мне образец? – Tohid 2012-11-14 14:28:01
Учитывая ответ:
HttpWebRequest webRequest;
void StartWebRequest()
{
webRequest.BeginGetResponse(new AsyncCallback(FinishWebRequest), null);
}
void FinishWebRequest(IAsyncResult result)
{
webRequest.EndGetResponse(result);
}
Вы можете отправить указатель запроса или любой другой объект, как это:
void StartWebRequest()
{
HttpWebRequest webRequest = ...;
webRequest.BeginGetResponse(new AsyncCallback(FinishWebRequest), webRequest);
}
void FinishWebRequest(IAsyncResult result)
{
HttpWebResponse response = (result.AsyncState as HttpWebRequest).EndGetResponse(result) as HttpWebResponse;
}
Greetings
public void GetResponseAsync (HttpWebRequest request, Action<HttpWebResponse> gotResponse)
{
if (request != null) {
request.BeginGetRequestStream ((r) => {
try { // there's a try/catch here because execution path is different from invokation one, exception here may cause a crash
HttpWebResponse response = request.EndGetResponse (r);
if (gotResponse != null)
gotResponse (response);
} catch (Exception x) {
Console.WriteLine ("Unable to get response for '" + request.RequestUri + "' Err: " + x);
}
}, null);
}
}
Все до сих пор было не так, потому что BeginGetResponse()
выполняет некоторую работу над текущей нитью. Из documentation:
Метод BeginGetResponse требует некоторых синхронных задач настройки для полной (разрешение DNS, прокси обнаружения и сокет-соединение TCP, к примеру), прежде чем этот метод становится асинхронным. В результате этот метод никогда не следует вызывать в потоке пользовательского интерфейса (UI) , потому что для завершения начальных синхронных задач установки может потребоваться значительное время (до нескольких минут ) в качестве исключения для ошибка или метод преуспевает.
Так, чтобы сделать это правильно:
void DoWithResponse(HttpWebRequest request, Action<HttpWebResponse> responseAction)
{
Action wrapperAction =() =>
{
request.BeginGetResponse(new AsyncCallback((iar) =>
{
var response = (HttpWebResponse)((HttpWebRequest)iar.AsyncState).EndGetResponse(iar);
responseAction(response);
}), request);
};
wrapperAction.BeginInvoke(new AsyncCallback((iar) =>
{
var action = (Action)iar.AsyncState;
action.EndInvoke(iar);
}), wrapperAction);
}
Вы можете делать то, что вам нужно с ответом. Например:
HttpWebRequest request;
// init your request...then:
DoWithResponse(request, (response) => {
var body = new StreamReader(response.GetResponseStream()).ReadToEnd();
Console.Write(body);
});
Я закончил с использованием BackgroundWorker, это, безусловно, асинхронно в отличие от некоторых из перечисленных выше решений, он обрабатывает возвращение к GUI нить для вас, и это очень легко понять.
Это также очень легко обрабатывать исключения, так как они в конечном итоге в методе RunWorkerCompleted, но убедитесь, что вы читаете это: Unhandled exceptions in BackgroundWorker
Я использовал WebClient, но очевидно, что вы могли бы использовать HttpWebRequest.GetResponse, если вы хотите.
var worker = new BackgroundWorker();
worker.DoWork += (sender, args) => {
args.Result = new WebClient().DownloadString(settings.test_url);
};
worker.RunWorkerCompleted += (sender, e) => {
if (e.Error != null) {
connectivityLabel.Text = "Error: " + e.Error.Message;
} else {
connectivityLabel.Text = "Connectivity OK";
Log.d("result:" + e.Result);
}
};
connectivityLabel.Text = "Testing Connectivity";
worker.RunWorkerAsync();
К самым простым способом является использование TaskFactory.FromAsync из TPL. Это буквально пару строк кода при использовании в сочетании с новыми async/await ключевые слова:
var request = WebRequest.Create("http://www.stackoverflow.com");
var response = (HttpWebResponse) await Task.Factory
.FromAsync<WebResponse>(request.BeginGetResponse,
request.EndGetResponse,
null);
Debug.Assert(response.StatusCode == HttpStatusCode.OK);
Если вы не можете использовать C# 5 компилятор, то выше можно выполнить с помощью Task.ContinueWith метода:
Task.Factory.FromAsync<WebResponse>(request.BeginGetResponse,
request.EndGetResponse,
null)
.ContinueWith(task =>
{
var response = (HttpWebResponse) task.Result;
Debug.Assert(response.StatusCode == HttpStatusCode.OK);
});
.NET изменилась, поскольку многие из этих ответов были опубликованы, и я хотел бы предоставить более современный ответ. Используйте метод асинхронного начать Task
, который будет работать в фоновом потоке:
private async Task<String> MakeRequestAsync(String url)
{
String responseText = await Task.Run(() =>
{
try
{
HttpWebRequest request = WebRequest.Create(url) as HttpWebRequest;
WebResponse response = request.GetResponse();
Stream responseStream = response.GetResponseStream();
return new StreamReader(responseStream).ReadToEnd();
}
catch (Exception e)
{
Console.WriteLine("Error: " + e.Message);
}
return null;
});
return responseText;
}
Чтобы использовать метод асинхронного:
String response = await MakeRequestAsync("http://example.com/");
- 1. Как анализировать XML из HttpWebRequest асинхронно?
- 2. Поддержка .NET Proxy - HTTPWebRequest
- 3. Ошибка .NET HttpWebRequest HTTPS
- 4. Debug .NET HttpWebRequest
- 5. Как использовать DataAdapter.Fill() асинхронно?
- 6. Как использовать SaveFileDialog асинхронно?
- 7. Как позвонить HttpWebRequest в C# .net
- 8. .Net HttpWebRequest/Response Cocoa Equivelant
- 9. скачать онлайн изображение асинхронно в .Net
- 10. Как выполнить действие асинхронно в .net 4
- 11. .NET Threading - HttpWebRequest BeginGetResponse + AutoResetEvent
- 12. .NET HttpWebRequest Скорость против браузера
- 13. Как использовать log4j's FileAppenders асинхронно?
- 14. Как использовать «WinHttp.WinHttpRequest.5.1» асинхронно?
- 15. Как использовать php-функцию асинхронно
- 16. Как я могу использовать Directory.EnumerateFileSystemEntries() асинхронно?
- 17. Асинхронно используя HttpWebRequest без блокировки потока пользовательского интерфейса
- 18. Невозможно использовать httpwebrequest со списком
- 19. .Net асинхронно вызывает частичный вид
- 20. Как клонировать HttpWebRequest?
- 21. Как запросить базу данных асинхронно в .NET.
- 22. Использовать IComparer асинхронно в C#
- 23. .Net - WebClient или HttpWebRequest для получения контента
- 24. Зачем использовать ReadDirectoryChangesW асинхронно?
- 25. Что такое хороший прецедент для чтения потока ответов HttpWebRequest асинхронно?
- 26. Вопрос о HttpWebRequest классе в .net
- 27. Эквивалент WebClient .NET и HttpWebRequest в Java?
- 28. .Net CF/HttpWebRequest и «WebException был необработанным»
- 29. Как использовать HttpWebRequest с помощью метода GET
- 30. Как использовать файлы cookie с HttpWebRequest
использование асинхронным http://msdn.microsoft.com/en-us /library/system.net.webrequest.endgetrequeststream.aspx – 2010-03-26 22:55:41
на какое-то время, я задавался вопросом, пытаетесь ли вы прокомментировать рекурсивный поток? – 2010-05-20 03:17:18
Вы также можете увидеть следующее, для довольно полного примера того, что делает Джейсон: http://stuff.seans.com/2009/01/05/using-httpwebrequest-for-asynchronous-downloads/ Sean – 2009-04-08 19:43:41