Встановити час очікування для webClient.DownloadFile ()


92

Я використовую webClient.DownloadFile()для завантаження файлу, чи можу я встановити час очікування для цього, щоб це не зайняло так багато часу, якщо він не може отримати доступ до файлу?

Відповіді:


42

Спробуйте WebClient.DownloadFileAsync(). Ви можете зателефонувати CancelAsync()за таймером із власним тайм-аутом.


2
Я не хочу використовувати таймер або секундомір. Я хочу вбудований підхід хакерства або API. Використання таймера / секундоміра коштує мені додаткового потоку для перегляду, хоча ця функція, можливо, вже реалізована, то чому навіщо винаходити колесо

@Kilanny: тоді перейдіть до рішення з іншої відповіді. Або скористайтеся HttpClient і встановіть властивість Timeout. Також зверніть увагу, що ця відповідь від 2009 року.
Абатищев,

8
у .Net 4.5+ ви також можете використовувати, var taskDownload = client.DownloadFileTaskAsync(new Uri("http://localhost/folder"),"filename")а потімtaskDownload.Wait(TimeSpan.FromSeconds(5));
його

257

Моя відповідь звідси

Ви можете створити похідний клас, який встановить властивість тайм-ауту базового WebRequestкласу:

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

і ви можете використовувати його так само, як базовий клас WebClient.


3
Просто якщо хтось ще натрапить на цей корисний код, мені довелося встановити час очікування перед викликом бази. GetWebRequest (адреса)
Дарттонг,

Resharper скаржиться на можливе нульове значення для "result" і пропонує перевірку на нуль перед тим, як встановити значення Timeout для WebRequest. Дивлячись на декомпільований код, здається неможливим, якщо ви не надасте власні WebRequestModules у своєму web.config, але для такої схваленої відповіді я додав би його про всяк випадок.
Кевін Куломбе,

Я отримую помилку в цьому рядку request.Timeout. Помилка повідомлення '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?) , чого мені не вистачає?
Ерік

1
@Eric: Я додав usingдирективи, які використовуються цим фрагментом коду.
Беніамін

1
@titol: використовуйте HttpClient, а не WebClient.
абатищев

3

Якщо припустити, що ви хотіли зробити це синхронно, за допомогою методу WebClient.OpenRead (...) та встановлення часу очікування на потоці, який він повертає, дасть вам бажаний результат:

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

Виведення з WebClient та перевизначення GetWebRequest (...) для встановлення тайм-ауту, запропонованого @Beniamin, не працювали для мене як, але це так.


@jeffymorris у мене не спрацював. Я все ще отримую WebException, який каже: "запит перервано - операція закінчилась", навіть якщо я вказав stream.ReadTimeoutбільше, ніж насправді знадобилося для виконання запиту
chester89

@jeffymoris, з іншого боку, рішення з підкласом webclient теж не спрацювало, тому це, мабуть, проблема на стороні сервера
chester89
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.