views:

414

answers:

1

When calling WebClient.UploadStringAsync twice, without waiting for the WebClient.UploadStringCompleted event, the following exception is thrown:

"WebClient does not support concurrent I/O operations"

Apparently, this is not supported.

The reason for wanting to start multiple HTTP POST requests without having to wait for the previous response to arrive is because of performance; I want to avoid the round trip delay. Is there a workaround for this limitation?

+4  A: 

You need to use multiple instances of WebClient.

 var wc1 = new WebClient();
 wc1.UploadStringCompleted += (s, args) => {
    // do stuff when first upload completes
 }
 wc1.UploadString(uri1,str1);

 var wc2 = new WebClient();
 wc2.UploadStringCompleted += (s, args) => {
    // do stuff when second upload completes
    // might happen before first has completed
 }
 wc2.UploadString(uri2,str2);
AnthonyWJones
Thanks for your response! I had already tried to create a new WebClient instance for every HTTP request, but I rejected it, because every new instance causes a new HTTP connection to be set up, and I was afraid this would be too slow. However, as you suggest this is the way to go, I'll re-evaluate this solution.
Dimitri C.
@Dimitri: I'm not entirely sure that each WebClient creates a new connection, it could do. OTH it could leave actual connection management to the underlying browser HTTP stack (I think thats more likely but I could be wrong). Use the sysinternals tcpview.exe tool http://live.sysinternals.com/ to observe it. Besides as I understand it you want multiple concurrent requests, right? Well very few HTTP stacks out there allow that on the same connection despite that being possible in the HTTP/1.1 spec. I'm pretty sure Microsoft don't support multiple concurrent requests on the same connection.
AnthonyWJones
@Anthony: I'm afraid you're right. Concurrent requests on a single connection seem impossible indeed. That's a pity, as it will undoubtedly hurt performance.
Dimitri C.
@Dimitri: TBH I doubt it. I'll have to at some point actually test and observe this for myself but I really think you'll find that multiple connections will be maintained and re-used for subsequent requests and that there will be enough of them open concurrently to handle any reasonable number of concurrent requests. Hence the extra overhead and complexity of the pipeline protocol will be surplus to requirements, which is probably why hardly anyone has bothered to support it.
AnthonyWJones
@Anthony: You are probably right that the communication can be made fast enough due to the multiple connections feature. I'll give your solution a try! Again, thank you very much for the feedback; it was of great help, as I'm not used to low-level HTTP issues. Unfortunately, I need to maintain the original sequence of the requests, which will make the request handler logic more difficult, but as long if it is possible and reasonably fast, I'm happy :-)
Dimitri C.