Search code examples
c#asynchronouswindows-phone-7webclient

How to 'await' a WebClient.UploadStringAsync request?


The async pattern seems to be call an asynchronous, then yield control after awaiting a result, which makes a lot of sense.

However the WebClient class UploadStringAsync method does not return a Task, instead it return void and so cannot be awaited. Instead an event handler can be defined. e.g.

public async Task FlushQueue() {
    attempt = 0;
    WebClient wc = new WebClient();
    while ((queue.Count > 0) && (attempt < ALLOWED_ATTEMPTS)) {

        // Copy 10 items from queue and put into buffer ...
        ...
        wc.UploadStringCompleted += (s, e) => {
            // if response 200 
            // Remove 10 sent items from queue
            // else attempt++ 
        };
        wc.UploadStringAsync("http://example.com/blah", "POST", buffer);

        // In an ideal world we could call UploadStringAsync like,
        // var response = await wc.UploadStringAsync("http://example.com/blah", "POST", buffer);
    }
}

However, this does not await a response and instead quickly rattles through lauching the maximum number of web requests.

Is there a way to yield flow back outside of FlushQueue until the event handler callback is executed?

Edit: This is for a Windows Phone 7.5 project.


Solution

  • You need to use UploadStringTaskAsync, which returns a Task<string>.

    The async suffixes on pre-4.5 WebClient methods are unfortunate as they don't match the TAP signatures you'd expect. In general, in that situation it's recommended that API designers use TaskAsync instead of a Async as a suffix - which is exactly what WebClient did... hence DownloadStringTaskAsync etc.

    You might also want to consider using HttpClient instead of WebClient.