example data code c# asynchronous httpwebrequest httpwebresponse

data - webrequest post parameters c#



Obtener la respuesta de un HttpWebRequest asíncrono (4)

"Incluso mejor sería cambiar a HttpClient si estás usando .NET 4.5, ya que es asíncrono ''nativo''". - Respuesta absolutamente correcta por James Manning. Esta pregunta fue formulada hace aproximadamente 2 años. Ahora tenemos .NET Framework 4.5, que proporciona poderosos métodos asíncronos. Utilice HttpClient. Considere el siguiente código:

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 } } }

Para usar HttpGetAsync (), crea un nuevo método que sea "asíncrono" también. se requiere async, porque necesitamos usar "await" en el método GetWebPage ():

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

Ahora, si desea obtener el código fuente HTML de la página web de forma asíncrona, simplemente llame a GetWebPage ("dirección web ..."). Incluso la lectura de la secuencia es asíncrona.

NOTA: para utilizar HttpClient .NET framework 4.5 es necesario. También necesita agregar la referencia System.Net.Http en su proyecto y agregar también " using System.Net.Http " para un fácil acceso.

Para obtener más información sobre cómo funciona este enfoque, visite: http://msdn.microsoft.com/en-us/library/hh191443(v=vs.110).aspx

Uso de Async: Async en 4.5: Vale la pena la espera

Me pregunto si hay una manera fácil de obtener la respuesta de una httpwebrequest asíncrona.

Ya he visto esta pregunta here pero todo lo que trato de hacer es devolver la respuesta (que generalmente es json o xml) en forma de cadena a otro método en el que luego puedo analizarla / tratarla en consecuencia.

Heres algún código:

Tengo estos dos métodos estáticos aquí, que creo que son seguros para subprocesos, ya que todos los parámetros se pasan y no hay variables locales compartidas que los métodos utilizan.

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; } }


Suponiendo que el problema es que está teniendo dificultades para acceder al contenido devuelto, la ruta más sencilla probablemente sería usar async / await si puede usarlo. Aún mejor sería cambiar a HttpClient si está utilizando .NET 4.5, ya que es asíncrono "nativo".

Al usar .NET 4 y C # 4, aún puede usar la Tarea para envolverlos y facilitar el acceso al resultado final. Por ejemplo, una opción sería la siguiente. Tenga en cuenta que tiene el método Main bloqueado hasta que la cadena de contenido esté disponible, pero en un escenario "real" probablemente pasaría la tarea a otra cosa o encadenaría otro ContinueWith fuera de él o lo que sea.

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; } }


Una vez que vas async, nunca puedes volver atrás. Desde allí, solo tienes acceso a la devolución de llamada de async. puede aumentar la complejidad de esto y hacer algunos threading y waithandles pero eso puede ser un esfuerzo bastante doloroso.

Técnicamente, también puede dormir el hilo cuando necesita esperar los resultados, pero no lo recomiendo, también puede hacer una solicitud http normal en ese momento.

En C # 5 tienen comandos async / await que harán más fácil obtener los resultados de la llamada async al hilo principal.


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); }