261 votes

Comment modifier le délai d'attente d'un objet WebClient .NET ?

J'essaie de télécharger les données d'un client sur ma machine locale (par programme) et leur serveur web est très, très lent, ce qui provoque un dépassement de délai dans mon WebClient objet.

Voici mon code :

WebClient webClient = new WebClient();

webClient.Encoding = Encoding.UTF8;
webClient.DownloadFile(downloadUrl, downloadFile);

Existe-t-il un moyen de définir un délai d'attente infini pour cet objet ? Si ce n'est pas le cas, est-ce que quelqu'un peut m'aider avec un exemple d'une autre façon de faire ?

L'URL fonctionne bien dans un navigateur - il faut juste environ 3 minutes pour qu'elle s'affiche.

432voto

kisp Points 1542

Vous pouvez étendre le délai d'attente : héritez de la classe WebClient d'origine et remplacez la fonction webrequest getter pour définir votre propre délai d'attente, comme dans l'exemple suivant.

Dans mon cas, MyWebClient était une classe privée :

private class MyWebClient : WebClient
{
    protected override WebRequest GetWebRequest(Uri uri)
    {
        WebRequest w = base.GetWebRequest(uri);
        w.Timeout = 20 * 60 * 1000;
        return w;
    }
}

6 votes

Quel est le délai d'attente par défaut ?

26 votes

Le délai par défaut est de 100 secondes. Bien qu'il semble fonctionner pendant 30 secondes.

0 votes

+1 pour la solution la plus simple, sans avoir à réécrire tout le code impliqué, lors de l'utilisation de HttpWebRequest & HttpWebResponse

24voto

Steve Fenton Points 55265

Vous devez utiliser HttpWebRequest plutôt que WebClient car vous ne pouvez pas définir le délai d'attente sur WebClient sans l'étendre (même s'il utilise les HttpWebRequest ). L'utilisation de HttpWebRequest place vous permettra de définir le délai d'attente.

0 votes

Ce n'est pas vrai... vous pouvez voir ci-dessus que vous pouvez toujours utiliser WebClient, bien qu'il s'agisse d'une implémentation personnalisée qui surcharge le WebRequest pour définir le délai d'attente.

8 votes

System.Net.HttpWebRequest.HttpWebRequest()" est obsolète : "Cette API prend en charge l'infrastructure .NET Framework et n'est pas destinée à être utilisée directement à partir de votre code".

4 votes

@usefulBee - parce que vous ne devriez pas appeler ce constructeur : "Do not use the HttpWebRequest constructor. Use the WebRequest.Create method to initialize new HttpWebRequest objects." de msdn.microsoft.com/en-us/library/ . Voir aussi stackoverflow.com/questions/400565/

11voto

GlennG Points 909

Pour être complet, voici la solution de kisp portée en VB (on ne peut pas ajouter de 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

0 votes

L'auteur a demandé une solution pour le langage C#, pas pour Visual Basic.

1 votes

Pour être complet, il s'agit d'une solution VB pour les personnes utilisant VB qui lisent ce site et qui pourraient avoir besoin d'un portage du code C#. Comme moi.

7voto

dariom Points 3304

Comme le dit Sohnee, l'utilisation de System.Net.HttpWebRequest et définir le Timeout au lieu d'utiliser la propriété System.Net.WebClient .

Vous ne pouvez cependant pas définir une valeur de délai infinie (ce n'est pas pris en charge et une tentative de ce type entraînera une erreur de type ArgumentOutOfRangeException ).

Je recommande d'abord d'effectuer une HEAD HTTP et l'examen de la demande de Content-Length renvoyée pour déterminer le nombre d'octets du fichier que vous téléchargez, puis définir la valeur du délai d'attente en conséquence pour les téléchargements suivants. GET ou simplement en spécifiant une valeur de délai très longue que l'on ne s'attend pas à dépasser.

7voto

Josh Points 51
'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

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X