none
WebClient UploadData Asynch o httWebClient RRS feed

  • Pregunta

  • Hola, tengo una aplicación que consume un servicio web, utilizo el objeto webclient y hago un pos con el metodo uploaddata, el problema es que cuando el servicio está caido o no hay red se queda esperando mucho tiempo así que necesito ponerle un timeout.

    Tengo entendido que el objeto httpwebclient tiene time out o que lo puedo hacer por el mismo objeto webclient pero con el metodo uploaddataasynch pero no le encuentro la vuelta y no hay un ejemplo completo porque una vez que envío los datos necesito recuperar la respuesta y no encuentro como. Me pueden dar una mano?

    Acá les copio el codigo que tengo actualmente funcionando:

    Public Function MakeRequest(pBaseUrl As String, pMetodo As String, pToken As String, pJson As String) As MktApiResponse
    
            Try
                Dim request As New WebClient
                request.Headers.Add("content-type", "application/json")
                request.Headers.Add("Authorization", "Basic " & pToken)
                If Strings.InStrRev(pBaseUrl, "/") = 1 Then
                    request.BaseAddress = pBaseUrl
                Else
                    request.BaseAddress = pBaseUrl & "/"
                End If
    
                Dim response As String = Encoding.ASCII.GetString(request.UploadData(pMetodo, Encoding.Default.GetBytes(pJson)))
                Dim js As New JavaScriptSerializer()
                Dim ApiResponse As MktApiResponse = js.Deserialize(Of MktApiResponse)(response)
    
                Return ApiResponse
    
            Catch ex As Exception
                Dim BadApiResponse As New MktApiResponse
                BadApiResponse.Message = ex.Message
                BadApiResponse.HasError = True
                BadApiResponse.Code = -1
                Return BadApiResponse
            End Try
    
        End Function

    • Cambiado Enrique M. Montejo martes, 27 de junio de 2017 6:04 Pregunta relacionada con servicio web.
    domingo, 25 de junio de 2017 3:53

Respuestas

  • En otro post en el que se planteó una pregunta parecida, sugirieron crear una clase heredada de WebClient y hacer un override del método GetWebRequest, lo cual permite ponerle un Timeout. Después, esa clase heredada la puedes usar exactamente igual que el WebClient, con la diferencia de que tiene un TimeOut.

    El ejemplo que venía en el post que menciono estaba hecho en C# (te lo copio debajo), pero el mismo principio sería igualmente aplicable en Visual Basic.

    using System;
    using System.Net;
    
    public class WebDownload : WebClient
    {
        /// <summary>
        /// Time in milliseconds
        /// </summary>
        public int Timeout { get; set; }
    
        public WebDownload() : this(60000) { }
    
        public WebDownload(int timeout)
        {
            this.Timeout = timeout;
        }
    
        protected override WebRequest GetWebRequest(Uri address)
        {
            var request = base.GetWebRequest(address);
            if (request != null)
            {
                request.Timeout = this.Timeout;
            }
            return request;
        }
    }

    domingo, 25 de junio de 2017 10:19

Todas las respuestas

  • En otro post en el que se planteó una pregunta parecida, sugirieron crear una clase heredada de WebClient y hacer un override del método GetWebRequest, lo cual permite ponerle un Timeout. Después, esa clase heredada la puedes usar exactamente igual que el WebClient, con la diferencia de que tiene un TimeOut.

    El ejemplo que venía en el post que menciono estaba hecho en C# (te lo copio debajo), pero el mismo principio sería igualmente aplicable en Visual Basic.

    using System;
    using System.Net;
    
    public class WebDownload : WebClient
    {
        /// <summary>
        /// Time in milliseconds
        /// </summary>
        public int Timeout { get; set; }
    
        public WebDownload() : this(60000) { }
    
        public WebDownload(int timeout)
        {
            this.Timeout = timeout;
        }
    
        protected override WebRequest GetWebRequest(Uri address)
        {
            var request = base.GetWebRequest(address);
            if (request != null)
            {
                request.Timeout = this.Timeout;
            }
            return request;
        }
    }

    domingo, 25 de junio de 2017 10:19
  • Si la página está caída igual envia respuesta Error 404 file No fund o algo así podrías leer la respuesta que la tienes almacenada en el bufer si encuentra tal string terminar la llamada, y para el caso de verificar la red; Me.Compiuter.NetWorck.IsAbialble  si es true conectada. Igualmente dejo otra pregunta similar donde tabién verifican la conexión

    https://social.msdn.microsoft.com/Forums/es-ES/72d76498-3a94-4acd-b7d8-7237c277e81f/saber-si-tengo-conexin-o-no-a-internet?forum=vbes


    • Editado Marcelo PF domingo, 25 de junio de 2017 10:32
    domingo, 25 de junio de 2017 10:24
  • Hola Alberto, lo probé y no funciona, se ve que agregarle una propiedad con nombre timeout no hace que el método tenga un timeout, así le pase un milisegundo se queda esperando la respuesta del servidor.
    lunes, 26 de junio de 2017 13:06
  • Hola Marcelo, 

    El problema que tenemos es que cuando la pagina o la conexión están saturadas, el tiempo en mostrar la pagina de error es de 60 segundos, ese tiempo es el que el usuario se queda mirando la pantalla y hoy día 60 segundos de espera para un usuario es una eternidad, queremos poner un time out de 5 segundos y si no hay respuesta salir con aviso de error pero no logro hacerlo.

    Quisiera hacer un uploaddataasynch pero no encuentro como recuperar la información.

    lunes, 26 de junio de 2017 13:11
  • Perdón Alberto, SI funciona, lo estaba implementando mal yo.

    Muchas gracias.

    Copio el código en vb por si a alguien le sirve:

    Public Class WebDownload : Inherits WebClient
    
    	''' <summary>
    	''' Time in milliseconds
    	''' </summary>
    	Public Property Timeout() As Integer
    
    	Public Sub New()
    		Me.New(60000)
    	End Sub
    
    	Public Sub New(ByVal timeout As Integer)
    		Me.Timeout = timeout
    	End Sub
    
    	Protected Overrides Function GetWebRequest(ByVal address As Uri) As WebRequest
    		Dim request = MyBase.GetWebRequest(address)
    		If request IsNot Nothing Then
    			request.Timeout = Me.Timeout
    		End If
    		Return request
    	End Function
    End Class
    

    lunes, 26 de junio de 2017 15:07