J
Jon Payne
I am trying to download a file using WebRequest / WebResponse using
HTTP over ActiveSync. I can successfully download the file but I am
seeing very poor performance (I have attached a copy of the code I am
using, below).
Copying a 4.6 MB file directly using ActiveSync takes 13 seconds.
Copying the same file using HTTP in 32 KB blocks is taking 83 seconds.
If I copy the file in 1000 byte blocks, I can get the time down to 40
seconds.
The really strange bit is that the code runs faster if I put a short
Thread.Sleep call in after each read. These are the results of some
tests I ran (I ran some of these multiple times and each time the
result was within +/- 2 seconds):
File size 4,664kb
Time Block Sleep
39.75 1000 None
58.80 15000 50
45.85 32769 100
27.34 32769 50
17.91 32769 25
17.28 32769 20
84.00 32769 15
84.17 32769 10
83.93 32769 0
83.83 32769 None
Where 'Time' is the time in seconds to complete the download, 'Block'
is the block size I used and 'Sleep' is the length of sleep between
each read call.
I am guessing that .Net has a background thread for the downloading
which is getting starved by the application thread if it does not sleep
between Read calls.
Is there a good way of doing this? I would like to be able to download
a file over HTTP as quickly as possible without resorting to ugly hacks
like Thread.Sleep.
This is the code I am testing with:
int tickCountStart = Environment.TickCount;
const int blockSize = 32769; // change this line to test block sizes
const int sleepTime = 20; // change this line to test sleeps
WebRequest request = WebRequest.Create("http://ppp_peer/bigfile.dat");
using (WebResponse response = request.GetResponse())
{
int remaining = (int)response.ContentLength;
using (Stream stream = response.GetResponseStream())
{
byte[] buffer = new byte[blockSize];
while (remaining > 0)
{
remaining -= stream.Read(buffer, 0, Math.Min(blockSize,
remaining));
Thread.Sleep(sleepTime);
}
}
}
int tickCountEnd = Environment.TickCount;
MessageBox.Show(string.Format("Time taken {0:n}", (tickCountEnd -
tickCountStart) / 1000.0));
Thanks
Jon Payne
HTTP over ActiveSync. I can successfully download the file but I am
seeing very poor performance (I have attached a copy of the code I am
using, below).
Copying a 4.6 MB file directly using ActiveSync takes 13 seconds.
Copying the same file using HTTP in 32 KB blocks is taking 83 seconds.
If I copy the file in 1000 byte blocks, I can get the time down to 40
seconds.
The really strange bit is that the code runs faster if I put a short
Thread.Sleep call in after each read. These are the results of some
tests I ran (I ran some of these multiple times and each time the
result was within +/- 2 seconds):
File size 4,664kb
Time Block Sleep
39.75 1000 None
58.80 15000 50
45.85 32769 100
27.34 32769 50
17.91 32769 25
17.28 32769 20
84.00 32769 15
84.17 32769 10
83.93 32769 0
83.83 32769 None
Where 'Time' is the time in seconds to complete the download, 'Block'
is the block size I used and 'Sleep' is the length of sleep between
each read call.
I am guessing that .Net has a background thread for the downloading
which is getting starved by the application thread if it does not sleep
between Read calls.
Is there a good way of doing this? I would like to be able to download
a file over HTTP as quickly as possible without resorting to ugly hacks
like Thread.Sleep.
This is the code I am testing with:
int tickCountStart = Environment.TickCount;
const int blockSize = 32769; // change this line to test block sizes
const int sleepTime = 20; // change this line to test sleeps
WebRequest request = WebRequest.Create("http://ppp_peer/bigfile.dat");
using (WebResponse response = request.GetResponse())
{
int remaining = (int)response.ContentLength;
using (Stream stream = response.GetResponseStream())
{
byte[] buffer = new byte[blockSize];
while (remaining > 0)
{
remaining -= stream.Read(buffer, 0, Math.Min(blockSize,
remaining));
Thread.Sleep(sleepTime);
}
}
}
int tickCountEnd = Environment.TickCount;
MessageBox.Show(string.Format("Time taken {0:n}", (tickCountEnd -
tickCountStart) / 1000.0));
Thanks
Jon Payne