6

I am using Webclient to download a file asynchronously. I am wondering how often is DownloadProgressChangedEventHandler get called? Can the user control it?

user496949
  • 83,087
  • 147
  • 309
  • 426

2 Answers2

2

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.

Ian Griffiths
  • 14,302
  • 2
  • 64
  • 88
0

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
Maxim Gershkovich
  • 45,951
  • 44
  • 147
  • 243