 <p>Taking a look at another client's code is helpful (if not confusing): <a href="http://src.chromium.org/viewvc/chrome/trunk/src/net/http/" rel="nofollow noreferrer">http://src.chromium.org/viewvc/chrome/trunk/src/net/http/</a></p> <p>I'm currently doing something like this too. I find the best way to increase the efficiency of the client is to use the asynchronous socket functions provided. They're quite low-level and get rid of busy waiting and dealing with threads yourself. All of these have <code>Begin</code> and <code>End</code> in their method names. But first, I would try it using blocking, just so you get the semantics of HTTP out of the way. Then you can work on efficiency. Remember: Premature optimization is evil- so get it working, then optimize all of the stuff!</p> <p>Also: Some of your efficiency might be tied up in your use of <code>ToArray()</code>. It's known to be a bit expensive computationally. A better solution might be to store your intermediate results in a <code>byte[]</code> buffer and append them to a <code>StringBuilder</code> with the correct encoding.</p> <p>For gzipped or deflated data, read in all of the data (keep in mind that you might not get all of the data the first time you ask. Keep track of how much data you have read in, and keep on appending to the same buffer). Then you can decode the data using <code>GZipStream(..., CompressionMode.Decompress)</code>.</p> <p>I would say that doing this is not as difficult as some might imply, you just have to be a bit adventurous!</p>