Zeitlimit für webClient festlegen.DownloadFile ()

92

Ich verwende webClient.DownloadFile()eine Datei herunterzuladen , kann ich einen Timeout für diesen Satz , so dass es nicht so lange dauern , wenn es nicht auf die Datei zugreifen kann?

UnkwnTech
quelle

Antworten:

42

Versuchen Sie es WebClient.DownloadFileAsync(). Sie können CancelAsync()per Timer mit Ihrer eigenen Zeitüberschreitung anrufen .

abatishchev
quelle
2
Ich möchte keinen Timer oder keine Stoppuhr verwenden. Ich möchte einen eingebauten Hack- oder API-Ansatz. Die Verwendung von Timer / Stoppuhr kostet mich zusätzlichen Thread zum Anschauen, während diese Funktion möglicherweise bereits implementiert ist. Warum also das Rad neu erfinden
@Kilanny: dann geh mit der Lösung aus einer anderen Antwort. Oder verwenden Sie HttpClient und legen Sie die Timeout-Eigenschaft fest. Bitte beachten Sie auch, dass diese Antwort aus dem Jahr 2009 stammt.
abatishchev
8
in .Net 4.5+ können Sie auch verwenden var taskDownload = client.DownloadFileTaskAsync(new Uri("http://localhost/folder"),"filename")und danntaskDownload.Wait(TimeSpan.FromSeconds(5));
itsho
257

Meine Antwort kommt von hier

Sie können eine abgeleitete Klasse erstellen, die die Timeout-Eigenschaft der Basisklasse WebRequestfestlegt:

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

und Sie können es genau wie die Basis-WebClient-Klasse verwenden.

Beniamin
quelle
3
Nur für den Fall, dass jemand anderes auf diesen hilfreichen Code stößt, musste ich das Zeitlimit festlegen, bevor ich base.GetWebRequest (Adresse)
anrief
Resharper beschwert sich über einen möglichen Nullwert für "Ergebnis" und schlägt eine Nullprüfung vor, bevor der Timeout-Wert auf WebRequest gesetzt wird. Wenn Sie sich den dekompilierten Code ansehen, ist es unmöglich, wenn Sie in Ihrer web.config kein benutzerdefiniertes WebRequestModules angeben. Für eine derart optimierte Antwort würde ich es jedoch nur für den Fall hinzufügen.
Kevin Coulombe
Ich erhalte den Fehler in dieser Zeile request.Timeout. Fehlermeldung 'System.Net.WebRequest' does not contain a definition for 'Timeout' and no extension method 'Timeout' accepting a first argument of type 'System.Net.WebRequest' could be found (are you missing a using directive or an assembly reference?) , was fehlt mir?
Eric
1
@Eric: Ich habe usingAnweisungen hinzugefügt , die von diesem Code-Snippet verwendet werden.
Beniamin
1
@titol: Verwenden Sie HttpClient anstelle von WebClient.
Abatishchev
3

Angenommen, Sie möchten dies synchron tun, indem Sie die WebClient.OpenRead (...) -Methode verwenden und das Zeitlimit für den zurückgegebenen Stream festlegen, erhalten Sie das gewünschte Ergebnis:

using (var webClient = new WebClient())
using (var stream = webClient.OpenRead(streamingUri))
{
     if (stream != null)
     {
          stream.ReadTimeout = Timeout.Infinite;
          using (var reader = new StreamReader(stream, Encoding.UTF8, false))
          {
               string line;
               while ((line = reader.ReadLine()) != null)
               {
                    if (line != String.Empty)
                    {
                        Console.WriteLine("Count {0}", count++);
                    }
                    Console.WriteLine(line);
               }
          }
     }
}

Das Ableiten von WebClient und das Überschreiben von GetWebRequest (...) zum Festlegen des von @Beniamin vorgeschlagenen Zeitlimits hat bei mir nicht funktioniert, aber das hat funktioniert.

jeffrymorris
quelle
@ Jeffymorris hat bei mir nicht funktioniert. Ich erhalte immer noch die WebException mit der Meldung "Die Anforderung wurde abgebrochen - der Vorgang ist abgelaufen", auch wenn ich einen stream.ReadTimeoutgrößeren
Wert
@ Jeffymoris auf der anderen Seite, die Lösung mit Webclient-Unterklasse funktionierte auch nicht, so ist es wahrscheinlich ein Problem auf der Serverseite
Chester89