I had thought this was a reasonable pattern to use to call WebClient DownloadData asynchronously in an event handler:
private async void button1_Click(object sender, EventArgs e)
{
WebClient wc = new WebClient();
//wc.Proxy = null;
byte[] bytes = await wc.DownloadDataTaskAsync("http://www.google.com");
label1.Text = Encoding.ASCII.GetString(bytes);
}
But I find DownloadDataTaskAsync blocks for about 5 seconds before returning (unless the wc.Proxy = null statement is uncommented). What's the point of a method being awaitable if it can at a whim perform non-trivial work before even returning the task?
Presumably this means to be safe I should never call xAsync methods as above but instead should always wrap them in a Task.Run() myself to be sure. Or not?
This is a known issue with WebClient
/HttpWebRequest
: the proxies and DNS lookups are always done synchronously. This is a bug, but Microsoft has pretty much decided not to fix it for backwards compatibility reasons.
The first thing I'd recommend is to use HttpClient
. If that doesn't work and you need asynchrony, then you can wrap the call in Task.Run
.
It turns out that WebClient.DownloadDataTaskAsync is calling HttpWebRequest.BeginGetResponse
MSDN points out:
The BeginGetResponse method requires some synchronous setup tasks to complete (DNS resolution, proxy detection, and TCP socket connection, for example) before this method becomes asynchronous. As a result, this method should never be called on a user interface (UI) thread because it might take considerable time (up to several minutes depending on network settings) to complete the initial synchronous setup tasks before an exception for an error is thrown or the method succeeds.
http://msdn.microsoft.com/en-us/library/system.net.httpwebrequest.begingetresponse(v=vs.110).aspx
Unfortunately the MSDN documentation for WebClient.DownloadDataTaskAsync says:
This operation will not block.
which seems to not be strictly true.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With