WebClient.DownloadFile в производительности BackgroundWorker недопустимо - PullRequest
0 голосов
/ 30 мая 2011

У меня есть приложение WinForms, которое должно загружать много (десятки тысяч) довольно больших (несколько МБ) файлов в день. Я написал простой тест, используя следующий код:

using (var wc = new System.Net.WebClient())
{
    foreach (string url in UrlsToDownload())
    {
        string targetPath = SafeFilePathOf(url);
        wc.DownloadFile(url, targetPath);
    }
}

Целевая машина имеет соединение 1 Гбит / с, но тестирование показывает устойчивую загрузку около 1 МБ / с. Это меньше, чем я ожидал, но исходные серверы могут иметь более медленные соединения. Для загрузки полного дня потребуется несколько часов подключения, что является приемлемым. Использование сети довольно постоянное и составляет около 1%:

Загрузить файл в потоке пользовательского интерфейса Тем не менее, мне нужно выполнять загрузку в фоновом потоке и поддерживать отмену и прогресс загрузки. .Net System.ComponentModel.BackgroundWorker кажется разработанным для этого, поэтому я помещаю точно такой же код в экземпляр BackgroundWorker и вызываю RunWorkerAsync: Загрузить файл в BackgroundWorker

Скорость загрузки падает до 0,05 МБ / с. Работа в течение дня потребует около недели; это не полетит.

Почему производительность BackgroundWorker так плоха? Ни процессор, ни сеть не перегружены. Приложение не заблокировано, я просто переместил код загрузки из потока пользовательского интерфейса в BackgroundWorker. Вызов backgroundWorker.Priority = ThreadPriority.AboveNormal не имеет никакого эффекта.

Ответы [ 2 ]

0 голосов
/ 09 января 2013

Увеличение лимита подключения на WebClient:

internal class CustomWebClient : WebClient
{
    public CustomWebClient()
    {
    }

    protected override WebRequest GetWebRequest(Uri uri)
    {
        HttpWebRequest w = (HttpWebRequest)base.GetWebRequest(uri);

        w.ServicePoint.ConnectionLimit = 100;
        return w;
    }
}
0 голосов
/ 31 мая 2011

Сетевая активность выполняется одинаково, будь то фоновый поток или поток пользовательского интерфейса.Проблема может быть в любом другом коде, сообщающем о прогрессе, регистрации и т. Д., Который может блокировать поток.

...