c# - from - Cómo cambiar el tiempo de espera en un objeto WebClient.NET
webclient downloadfile c# timeout (7)
Como dice Sohnee, usar System.Net.HttpWebRequest
y establecer la propiedad Timeout
lugar de usar System.Net.WebClient
.
Sin embargo, no puede establecer un valor de tiempo de espera infinito (no se admite y al intentar hacerlo se lanzará una ArgumentOutOfRangeException
).
Recomiendo realizar primero una solicitud HEAD HTTP y examinar el valor del encabezado Content-Length
devuelto para determinar la cantidad de bytes en el archivo que está descargando y luego establecer el valor de tiempo de espera correspondiente para la solicitud GET
posterior o simplemente especificar un tiempo de espera muy largo Valor que nunca esperarías superar.
Estoy tratando de descargar los datos de un cliente a mi máquina local (programáticamente) y su servidor web es muy, muy lento, lo que está causando un tiempo de espera en mi objeto WebClient
.
Aquí está mi código:
WebClient webClient = new WebClient();
webClient.Encoding = Encoding.UTF8;
webClient.DownloadFile(downloadUrl, downloadFile);
¿Hay una manera de establecer un tiempo de espera infinito en este objeto? ¿O si no puede alguien ayudarme con un ejemplo de una manera alternativa de hacer esto?
La URL funciona bien en un navegador: solo demora unos 3 minutos en aparecer.
La primera solución no me funcionó, pero aquí hay un código que sí me funcionó.
private class WebClient : System.Net.WebClient
{
public int Timeout { get; set; }
protected override WebRequest GetWebRequest(Uri uri)
{
WebRequest lWebRequest = base.GetWebRequest(uri);
lWebRequest.Timeout = Timeout;
((HttpWebRequest)lWebRequest).ReadWriteTimeout = Timeout;
return lWebRequest;
}
}
private string GetRequest(string aURL)
{
using (var lWebClient = new WebClient())
{
lWebClient.Timeout = 600 * 60 * 1000;
return lWebClient.DownloadString(aURL);
}
}
No se pudo hacer funcionar el código w.Timeout cuando se extrajo el cable de red, simplemente no se agotó el tiempo de espera, se cambió para usar HttpWebRequest y hace el trabajo ahora.
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(downloadUrl);
request.Timeout = 10000;
request.ReadWriteTimeout = 10000;
var wresp = (HttpWebResponse)request.GetResponse();
using (Stream file = File.OpenWrite(downloadFile))
{
wresp.GetResponseStream().CopyTo(file);
}
Para completar, aquí está la solución de Kisp portada a VB (no se puede agregar código a un comentario)
Namespace Utils
'''''' <summary>
'''''' Subclass of WebClient to provide access to the timeout property
'''''' </summary>
Public Class WebClient
Inherits System.Net.WebClient
Private _TimeoutMS As Integer = 0
Public Sub New()
MyBase.New()
End Sub
Public Sub New(ByVal TimeoutMS As Integer)
MyBase.New()
_TimeoutMS = TimeoutMS
End Sub
'''''' <summary>
'''''' Set the web call timeout in Milliseconds
'''''' </summary>
'''''' <value></value>
Public WriteOnly Property setTimeout() As Integer
Set(ByVal value As Integer)
_TimeoutMS = value
End Set
End Property
Protected Overrides Function GetWebRequest(ByVal address As System.Uri) As System.Net.WebRequest
Dim w As System.Net.WebRequest = MyBase.GetWebRequest(address)
If _TimeoutMS <> 0 Then
w.Timeout = _TimeoutMS
End If
Return w
End Function
End Class
End Namespace
Puede extender el tiempo de espera: heredar la clase de WebClient original y anular el captador de consultas web para establecer su propio tiempo de espera, como en el siguiente ejemplo. MyWebClient era una clase privada en mi caso
private class MyWebClient : WebClient
{
protected override WebRequest GetWebRequest(Uri uri)
{
WebRequest w = base.GetWebRequest(uri);
w.Timeout = 20 * 60 * 1000;
return w;
}
}
HttpWebRequest
usar HttpWebRequest
lugar de WebClient
ya que no puede configurar el tiempo de espera en WebClient
sin extenderlo (aunque use HttpWebRequest
). Usar el HttpWebRequest
en HttpWebRequest
lugar le permitirá establecer el tiempo de espera.
''CORRECTED VERSION OF LAST FUNCTION IN VISUAL BASIC BY GLENNG
Protected Overrides Function GetWebRequest(ByVal address As System.Uri) As System.Net.WebRequest
Dim w As System.Net.WebRequest = MyBase.GetWebRequest(address)
If _TimeoutMS <> 0 Then
w.Timeout = _TimeoutMS
End If
Return w ''<<< NOTICE: MyBase.GetWebRequest(address) DOES NOT WORK >>>
End Function