Ustaw limit czasu dla webClient.DownloadFile ()


92

Używam webClient.DownloadFile()do pobrania pliku. Czy mogę ustawić limit czasu, aby to nie potrwać tak długo, jeśli nie może uzyskać dostępu do pliku?

Odpowiedzi:


42

Spróbuj WebClient.DownloadFileAsync(). Możesz zadzwonić CancelAsync()według timera z własnym limitem czasu.


2
Nie chcę używać minutnika ani stopera. Chcę mieć wbudowane podejście do hacka lub interfejsu API. Używanie timera / stopera kosztuje mnie dodatkowy wątek do oglądania, podczas gdy ta funkcja może już zaimplementowana, więc po co wymyślać koło na

@Kilanny: następnie przejdź do rozwiązania z innej odpowiedzi. Lub użyj HttpClient i ustaw właściwość Timeout. Proszę również zwrócić uwagę, że ta odpowiedź pochodzi z 2009 roku.
abatishchev

8
w .Net 4.5+ możesz również użyć, var taskDownload = client.DownloadFileTaskAsync(new Uri("http://localhost/folder"),"filename")a potemtaskDownload.Wait(TimeSpan.FromSeconds(5));
itsho

257

Moja odpowiedź pochodzi stąd

Możesz utworzyć klasę pochodną, ​​która ustawi właściwość timeout WebRequestklasy bazowej :

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

i można go używać tak samo, jak podstawowej klasy WebClient.


3
Nie rozczarować ktoś natknie tym pomocne kodu musiałem ustawić czas oczekiwania przed wywołaniem base.GetWebRequest (adres)
Darthtong

Resharper narzeka na możliwą wartość null dla „result” i sugeruje sprawdzenie wartości null przed ustawieniem wartości Timeout na WebRequest. Patrząc na zdekompilowany kod, wydaje się to niemożliwe, chyba że podasz niestandardowy moduł WebRequestModules w swoim pliku web.config, ale dla takiej pozytywnej odpowiedzi dodałbym go na wszelki wypadek.
Kevin Coulombe

W tej linii pojawia się błąd request.Timeout. Błąd msg '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?) , czego mi brakuje?
Eric,

1
@Eric: Dodałem usingdyrektywy używane przez ten fragment kodu.
Beniamin

1
@titol: użyj HttpClient zamiast WebClient.
abatishchev

3

Zakładając, że chciałeś to zrobić synchronicznie, używając metody WebClient.OpenRead (...) i ustawienie limitu czasu w zwracanym strumieniu da pożądany wynik:

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

Wyprowadzenie z WebClient i przesłanianie GetWebRequest (...) w celu ustawienia limitu czasu zasugerowanego przez @Beniamin nie działało dla mnie jako, ale tak się stało.


@jeffymorris nie działa dla mnie. Wciąż otrzymuję WebException z komunikatem „żądanie zostało przerwane - upłynął limit czasu operacji”, nawet jeśli stream.ReadTimeout
określę wartość

@jeffymoris z drugiej strony, rozwiązanie z podklasą webclient też nie działało, więc prawdopodobnie problem po stronie serwera
chester89
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.