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?

Antworten:


42

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


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.


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.


@ 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
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.