how to wait for webclient OpenReadAsync to complete
I would advise you to use WebClient.OpenReadTaskAsync
with a combination of the async/await
keywords introduced in .NET 4.5 instead. You need to add the async
keyword to your method, make it return a Task
and it is advisable to end your method with the Async
postfix:
MyCustomObject externalObj;
private static async Task CheckNetworkFileAsync()
{
try
{
WebClient webClient = new WebClient();
Stream stream = await webClient.OpenReadTaskAsync(new Uri("http://externalURl.com/sample.xml", UriKind.Absolute));
externalObj = myReadWebclientResponse(stream);
}
catch (Exception)
{
externalObj = null;
}
}
Edit:
As you said, WebClient.OpenReadTaskAsync
isn't available for WP8.1, So lets create an Extension Method so it will be:
public static class WebClientExtensions
{
public static Task<Stream> OpenReadTaskAsync(this WebClient client, Uri uri)
{
var tcs = new TaskCompletionSource<Stream>();
OpenReadCompletedEventHandler openReadEventHandler = null;
openReadEventHandler = (sender, args) =>
{
try
{
tcs.SetResult(args.Result);
}
catch (Exception e)
{
tcs.SetException(e);
}
};
client.OpenReadCompleted += openReadEventHandler;
client.OpenReadAsync(uri);
return tcs.Task;
}
}
Now you can use it on your WebClient
.
You can find great reading material in the async-await wiki and by simply filtering by that tag in the search bar.
Mahender
Updated on June 05, 2022Comments
-
Mahender almost 2 years
I am using WebClient to download some stuff from internet in Windows Phone 8.1 app. Below is the sample code i am using in my app - where i am calling below method, but my webclient is not waiting to complete the read operation and returning immediately after OpenReadAsync call.
how can i make sure that my method return operation must wait till OpenReadCompleted event is completed? I have seen multiple similar questions, but couldn't find a solution.
MyCustomObject externalObj; // my custom object private static void CheckNetworkFile() { try { WebClient webClient = new WebClient(); webClient.OpenReadCompleted += (s, e) => { externalObj = myReadWebclientResponse(e.Result); // my custom method to read the response }; webClient.OpenReadAsync(new Uri("http://externalURl.com/sample.xml", UriKind.Absolute)); } catch (Exception) { externalObj = null; } }
-
Mahender over 9 yearsThanks for the reply, actually this OpenReadTaskAsync() is not in the WindowsPhone platform.
-
Sayed Abolfazl Fatemi almost 9 yearsSalam, I think you must change "taskComplete" to "tcs.SetResult(...)"
-
Yuval Itzchakov almost 9 years@SayedAbolfazlFatemi Thanks for letting me know. Edited my answer.
-
Phil Cooper about 8 yearsThanks for the extension hint.
-
Christian Findlay over 7 yearsOH MY GOD!!! This is the single most important code example for Silverlight I have ever seen. This not only works for REST calls, it also works for WCF calls. Up until now, I have been using the old async model without the async/await operators to call WCF/REST methods. Our code is littered with horrible event handlers everywhere and the code is like a maze to navigate. This will clean up our code immensely. I should mention though, that in order to use this, we must add the Microsoft.Bcl.Async NuGet package. That was the other key to unlocking this problem.