Take the 2-minute tour ×

I use this code to read a HttpWebResponse stream

                Stream stm = httpResp.GetResponseStream();
                Stream fs = new FileStream(filename, FileMode.Append, FileAccess.Write);
                byte[] buff = new byte[1024 * 16];

                AsyncCallback callback = null;
                callback = ar =>
                    int bytesRead = stm.EndRead(ar);
                    fs.Write(buff, 0, bytesRead);
                    if(bytesRead == 0)

                    stm.BeginRead(buff, 0, buff.Length, callback, null);

I want to limit the download rate. If I put a Thread.Sleep() inside the callback , it will keep the thread blocked, but it will not scale well with many streams. Is there any other way to achieve download limit and thread economy?

share|improve this question
Are you sure that limits the download rate? –  Jim Mischel Mar 16 '13 at 12:20
I think yes, if it pauses between chunks of data –  albert Mar 16 '13 at 12:30
You might want to test it. I think you'll be surprised. –  Jim Mischel Mar 16 '13 at 17:12
I tested it and I saw some delay between the chunks of data. The total time of downloading the file was bigger (That's what I wanted). Are you offering some alternative? –  albert Mar 16 '13 at 17:58
I'm suggesting that the network stack will continue to receive the data and buffer it, so adding the delay in your code only controls how fast your program gets the data, not how fast it's downloaded from the server. –  Jim Mischel Mar 16 '13 at 19:02
show 1 more comment

1 Answer

Putting a sleep inside the loop might limit the download rate. It depends on the underlying protocol implementation and the size of the internal network stream buffer.

On my system (Windows Server 2008, .NET 4.5), putting a sleep in the loop does limit the download speed.

It also depends on the setting of the request.AllowReadStreamBuffering property. Documentation says that the default setting is true, but my testing shows that the default is false on my system. And in fact, trying to set it to true throws an exception.

However, it appears that the default is true for Silverlight. See the Silverlight doc for that property. When set to true, the entire response is read and buffered before the response is ready to be read.

Assuming that limiting the rate of read requests will limit the download rate (which seems reasonable, provided you disable read stream buffering), I don't see a good way to do it with BeginRead/EndRead. As you point out, putting a Thread.Sleep in there isn't going to scale well.

With .NET 4.5 and C# 5.0, you should consider using GetResponseAsync to get the response, and ReadAsync when reading the response stream. With .NET 4.0, you can create a Task to do the reading. Either of those will let you use Task.Delay to create your delays. This will have the same effect as Thread.Sleep in controlling the download speed, but will not block the thread.

Unfortunately, I don't have an example for you.

share|improve this answer
add comment

Your Answer


