I am using Webclient to download a file asynchronously. I am wondering how often is DownloadProgressChangedEventHandler get called? Can the user control it?
2 Answers
The following applies to the full .NET Framework, since your question is tagged ASP.NET. (Things might be different in Silverlight.)
Short answer: it's complex, the behaviour depends on various things including network performance characteristics, so it's inconsistent and you can't easily control it.
Long answer:
The event will typically be raised each time the underlying stream provided by the WebResponse
invokes the completion callback for the BeginRead
operation that WebClient
uses to perform asynchronous downloads.
It looks like WebClient
will typically attempt to read data in 64k chunks. However, streams are not required to return as much data as the called asked for - it's entirely possible that a call to BeginRead
that requests 64k will return less. In fact, that's quite common for streams that read data from the network - they are likely to return a smaller amount of data shortly after it's available, rather than waiting until all 64k has come in.
So the exact answer depends on the stream in question, and may also depends to some extent on the nature and performance of the network connection.
WebClient
uses WebRequest.Create
to obtain the request/response implementation that will ultimately supply the stream, and that's an extensible mechanism - .NET has 5 built-in implementations of WebRequest
and it offers an extensibility mechanism that lets you register additional handlers. And it's the specific WebRequest
implementation that determines the nature of the stream.
So the frequency with which you get progress events is entirely up to the type of download you're doing - you can get different results depending on what sort of URL it is. (E.g., http vs ftp vs file, or whatever.)
I'm going to hazard a wild guess that you're using HTTP.
Even then, it's pretty complicated - the HttpWebResponse
doesn't always use the same kind of stream. For example, it can sometimes return a stream derived from MemoryStream
, sometimes it's of type ConnectStream
...
So you can't say with any certainty what size chunks the underlying stream is likely to return because you can't even be sure what type of stream you're likely to get.
As for whether you can control it, about the only way you could would be to provide a custom WebRequest
implementation for a custom URL scheme. But frankly, it's probably simpler just to write code that decides whether or not to do anything with any particular event rather than trying to change the frequency of the events.

- 14,302
- 2
- 64
- 88
Well my tests seem to suggest that it is largely indeterminate.
The event seems to never raise less than 828 bytes and it seems no more than 65536 bytes.
I've been unable to dig any specifics up from MSDN. Their description:
“This event is raised each time an asynchronous download makes progress. This event is raised when downloads are started using any of the following methods.”
Code used as follows:
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
Outputs:
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
10mb file the output changes to:
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

- 45,951
- 44
- 147
- 243
-
PS: Just noticed this was a C# question... Dont kill me for the VB code :-) – Maxim Gershkovich Nov 10 '10 at 14:57