WebRequest / WebResponse performance issues

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
 
J

Jon Payne

Hi Tomer,

I am testing this on a Symbol MC70 device running Windows Mobile 5 AKU
3.2.

I have also tried downloading the same file using the Socket class and
a simple socket based server. This method performed a lot better (I
think downloading the same file took around 12 seconds).

I would like to know if there is a way of fixing the WebRequest /
WebResponse classes but I think I might just implement the HTTP code
manually for my current project.

Jon
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top