Как часто будет вызываться DownloadProgressChangedEventHandler - PullRequest
6 голосов
/ 10 ноября 2010

Я использую Webclient для асинхронной загрузки файла.Мне интересно, как часто вызывается DownloadProgressChangedEventHandler?Может ли пользователь это контролировать?

Ответы [ 2 ]

2 голосов
/ 10 ноября 2010

Следующее относится ко всей .NET Framework, поскольку ваш вопрос помечен как ASP.NET. (В Silverlight все может быть иначе.)

Краткий ответ: это сложно, поведение зависит от различных факторов, в том числе от характеристик производительности сети, поэтому оно несовместимо, и вы не можете легко его контролировать.

Длинный ответ:

Событие обычно вызывается каждый раз, когда базовый поток, предоставленный WebResponse, вызывает обратный вызов завершения для операции BeginRead, которую WebClient использует для выполнения асинхронных загрузок.

Похоже, что WebClient, как правило, будет пытаться прочитать данные кусками по 64 КБ. Однако потоки не обязаны возвращать столько данных, сколько запрашиваемый вызываемый - вполне возможно, что вызов BeginRead, который запрашивает 64k, будет возвращать меньше. Фактически, это довольно распространено для потоков, которые читают данные из сети - они, скорее всего, вернут меньшее количество данных вскоре после того, как они станут доступны, вместо того, чтобы ждать, пока все 64 КБ не поступят.

Таким образом, точный ответ зависит от рассматриваемого потока, а также может в некоторой степени зависеть от характера и производительности сетевого соединения.

WebClient использует WebRequest.Create для получения реализации запроса / ответа, которая в конечном итоге предоставит поток, и это расширяемый механизм - .NET имеет 5 встроенных реализаций WebRequest и предлагает механизм расширяемости, который позволяет Вы регистрируете дополнительные обработчики. И именно конкретная реализация WebRequest определяет природу потока.

Таким образом, частота, с которой вы получаете события прогресса, полностью зависит от типа загрузки, которую вы делаете - вы можете получить разные результаты в зависимости от того, какой это тип URL. (Например, http против ftp против файла или что-то еще.)

Я рискну предположить, что вы используете HTTP.

Даже тогда это довольно сложно - HttpWebResponse не всегда использует один и тот же вид потока. Например, иногда он может возвращать поток, полученный из MemoryStream, иногда он имеет тип ConnectStream ...

Таким образом, вы не можете с уверенностью сказать, какой размер фрагментов может вернуть базовый поток, потому что вы даже не можете быть уверены, какой тип потока вы получите.

Что касается того, можете ли вы управлять им, то единственным способом, которым вы могли бы, было бы предоставить пользовательскую реализацию WebRequest для пользовательской схемы URL. Но, честно говоря, возможно, проще просто написать код, который решает, делать ли что-либо с каким-либо конкретным событием, а не пытаться изменить частоту событий.

0 голосов
/ 10 ноября 2010

Что ж, мои тесты показывают, что это в значительной степени неопределенно.

Кажется, что событие никогда не поднимается меньше, чем 828 байт, и кажется, что оно не превышает 65536 байт.

Мне не удалось найти какие-либо подробности из MSDN.Их описание:

«Это событие возникает каждый раз, когда происходит асинхронная загрузка.Это событие возникает, когда загрузка начинается с использованием любого из следующих методов. ”

Код используется следующим образом:

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        Dim client As New WebClient

        AddHandler client.DownloadFileCompleted, AddressOf DownloadFileCompleted
        AddHandler client.DownloadProgressChanged, AddressOf DownloadProgressCallback

        Dim uri As New Uri("http://ftp.iinet.net.au/test500MB.dat", UriKind.Absolute)

        client.DownloadFileAsync(uri, "test500MB.dat")
End Sub

Sub DownloadProgressCallback(ByVal sender As Object, ByVal e As DownloadProgressChangedEventArgs)

        Debug.Print("{0}    downloaded {1} of {2} bytes. {3} % complete... Difference: {4}", _
         CStr(e.UserState), e.BytesReceived, e.TotalBytesToReceive, e.ProgressPercentage, CLng(e.BytesReceived - m_LastValue))

        m_LastValue = e.BytesReceived
End Sub

Выходы:

 downloaded 27416820 of 500000000 bytes. 5 % complete... Difference: 36712
    downloaded 27482356 of 500000000 bytes. 5 % complete... Difference: 65536
    downloaded 27483184 of 500000000 bytes. 5 % complete... Difference: 828
    downloaded 27548720 of 500000000 bytes. 5 % complete... Difference: 65536
    downloaded 27550960 of 500000000 bytes. 5 % complete... Difference: 2240
    downloaded 27586260 of 500000000 bytes. 5 % complete... Difference: 35300
    downloaded 27651796 of 500000000 bytes. 5 % complete... Difference: 65536
    downloaded 27652624 of 500000000 bytes. 5 % complete... Difference: 828
    downloaded 27718160 of 500000000 bytes. 5 % complete... Difference: 65536
    downloaded 27718988 of 500000000 bytes. 5 % complete... Difference: 828
    downloaded 27755700 of 500000000 bytes. 5 % complete... Difference: 36712
    downloaded 27821236 of 500000000 bytes. 5 % complete... Difference: 65536
    downloaded 27822064 of 500000000 bytes. 5 % complete... Difference: 828
    downloaded 27887600 of 500000000 bytes. 5 % complete... Difference: 65536
    downloaded 27888428 of 500000000 bytes. 5 % complete... Difference: 828
    downloaded 27925140 of 500000000 bytes. 5 % complete... Difference: 36712
    downloaded 27990676 of 500000000 bytes. 5 % complete... Difference: 65536
    downloaded 27991504 of 500000000 bytes. 5 % complete... Difference: 828
    downloaded 28057040 of 500000000 bytes. 5 % complete... Difference: 65536
    downloaded 28057868 of 500000000 bytes. 5 % complete... Difference: 828
    downloaded 28094580 of 500000000 bytes. 5 % complete... Difference: 36712
    downloaded 28160116 of 500000000 bytes. 5 % complete... Difference: 65536
    downloaded 28160944 of 500000000 bytes. 5 % complete... Difference: 828
    downloaded 28226480 of 500000000 bytes. 5 % complete... Difference: 65536
    downloaded 28227308 of 500000000 bytes. 5 % complete... Difference: 828
    downloaded 28264020 of 500000000 bytes. 5 % complete... Difference: 36712
    downloaded 28329556 of 500000000 bytes. 5 % complete... Difference: 65536
    downloaded 28330384 of 500000000 bytes. 5 % complete... Difference: 828
    downloaded 28395920 of 500000000 bytes. 5 % complete... Difference: 65536

10 МБ файл выводится на:

downloaded 307533 of 10000000 bytes. 3 % complete... Difference: 28240
    downloaded 369661 of 10000000 bytes. 3 % complete... Difference: 62128
    downloaded 431789 of 10000000 bytes. 4 % complete... Difference: 62128
    downloaded 497325 of 10000000 bytes. 4 % complete... Difference: 65536
    downloaded 498153 of 10000000 bytes. 4 % complete... Difference: 828
    downloaded 553221 of 10000000 bytes. 5 % complete... Difference: 55068
    downloaded 618757 of 10000000 bytes. 6 % complete... Difference: 65536
    downloaded 619585 of 10000000 bytes. 6 % complete... Difference: 828
    downloaded 649237 of 10000000 bytes. 6 % complete... Difference: 29652
    downloaded 714773 of 10000000 bytes. 7 % complete... Difference: 65536
    downloaded 715601 of 10000000 bytes. 7 % complete... Difference: 828
    downloaded 748077 of 10000000 bytes. 7 % complete... Difference: 32476
    downloaded 813613 of 10000000 bytes. 8 % complete... Difference: 65536
    downloaded 814441 of 10000000 bytes. 8 % complete... Difference: 828
    downloaded 866685 of 10000000 bytes. 8 % complete... Difference: 52244
    downloaded 932221 of 10000000 bytes. 9 % complete... Difference: 65536
    downloaded 933049 of 10000000 bytes. 9 % complete... Difference: 828
    downloaded 982469 of 10000000 bytes. 9 % complete... Difference: 49420
    downloaded 1048005 of 10000000 bytes. 10 % complete... Difference: 65536
    downloaded 1048833 of 10000000 bytes. 10 % complete... Difference: 828
    downloaded 1114369 of 10000000 bytes. 11 % complete... Difference: 65536
    downloaded 1115197 of 10000000 bytes. 11 % complete... Difference: 828
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...