J'essaie de télécharger (par programme) les données d'un client sur mon ordinateur local et leur serveur Web est très, très lent, ce qui provoque un dépassement du délai d'attente de mon objet WebClient
.
Voici mon code:
WebClient webClient = new WebClient();
webClient.Encoding = Encoding.UTF8;
webClient.DownloadFile(downloadUrl, downloadFile);
Est-il possible de définir un délai d'expiration infini sur cet objet? Ou sinon, est-ce que quelqu'un peut m'aider avec un exemple sur un autre moyen de le faire?
L'URL fonctionne bien dans un navigateur - l'affichage ne prend que 3 minutes environ.
Vous pouvez prolonger le délai d'attente: hériter de la classe WebClient d'origine et remplacer le getter webrequest pour définir votre propre délai d'attente, comme dans l'exemple suivant.
MyWebClient était un cours privé dans mon cas:
private class MyWebClient : WebClient
{
protected override WebRequest GetWebRequest(Uri uri)
{
WebRequest w = base.GetWebRequest(uri);
w.Timeout = 20 * 60 * 1000;
return w;
}
}
La première solution n'a pas fonctionné pour moi, mais voici un code qui a fonctionné pour moi.
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);
}
}
Vous devez utiliser HttpWebRequest
plutôt que WebClient
car vous ne pouvez pas définir le délai d’attente sur WebClient
sans le prolonger (même s’il utilise HttpWebRequest
). L'utilisation de HttpWebRequest
vous permettra de définir le délai.
Impossible de faire fonctionner le code w.Timeout lorsque le câble réseau est débranché, il n’a pas dépassé le délai imparti, il est passé à l’utilisation de HttpWebRequest et effectue le travail à présent.
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);
}
Pour être complet, voici la solution de kisp portée sur VB (impossible d'ajouter du code à un commentaire)
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
'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
Comme le dit Sohnee, utilisez System.Net.HttpWebRequest
et définissez la propriété Timeout
au lieu d’utiliser _System.Net.WebClient
_.
Vous ne pouvez toutefois pas définir une valeur de délai d'expiration infini (cette option n'est pas prise en charge et toute tentative de le faire générera un ArgumentOutOfRangeException
).
Je recommanderais d'abord d'effectuer une requête HEAD HTTP et d'examiner la valeur d'en-tête _Content-Length
_ renvoyée pour déterminer le nombre d'octets dans le fichier que vous téléchargez, puis de définir la valeur de délai en conséquence, GET
demande ou spécifiez simplement une valeur de délai d'attente très longue que vous ne vous attendez jamais à dépasser.
Usage:
using (var client = new TimeoutWebClient(TimeSpan.FromSeconds(10)))
{
return await client.DownloadStringTaskAsync(url);
}
Classe:
using System;
using System.Net;
namespace Utilities
{
public class TimeoutWebClient : WebClient
{
public TimeSpan Timeout { get; set; }
public TimeoutWebClient(TimeSpan timeout)
{
Timeout = timeout;
}
protected override WebRequest GetWebRequest(Uri uri)
{
var request = base.GetWebRequest(uri);
if (request == null)
{
return null;
}
var timeoutInMilliseconds = (int) Timeout.TotalMilliseconds;
request.Timeout = timeoutInMilliseconds;
if (request is HttpWebRequest httpWebRequest)
{
httpWebRequest.ReadWriteTimeout = timeoutInMilliseconds;
}
return request;
}
}
}