Reputation: 2466
I am working with a 3rd party library that is event based. I am really only interested in calling a library method and knowing when the library has finished. Pretty much like here: Convert Event based pattern to async CTP pattern
The thing is that the library seems to use Windows Phone's Background File Transfer
to do its job.
My symptom is that the library's completion handler is called only after my Task.Wait(TimeSpan.FromSeconds(5)) has timed out.
I tried to search for some docs about running Background File Transfer in the ThreadPool (as I assume in my async code, that's where the library is running), but couldn't really find any information. So could my issue (that completion handler is called only after timeout) be that Background File Transfer code shouldn't run in the ThreadPool?
Any ideas what a good approach for this kind of problem would be?
Upvotes: 1
Views: 186
Reputation: 61726
The pattern you linked is correct. It doesn't use async/await
but it doesn't use Task.Wait()
either. It returns a Task
object, and you're expected to await
on that task asynchronously. Which means, the code after await task
will be asynchronously invoked by the Task Scheduler when the task has reached the complete (faulted, cancelled) state.
Otherwise, you're blocking the UI thread and its message pump with the synchronous Task.Wait()
call, so the completion event doesn't have a chance to get fired properly.
To understand this issue better, here is a very good read: Don't Block on Async.
To correct your code, you'd have to make the whole chain of calls async
, up to the root, which in a UI app is usually an event handler. E.g.:
// note, "async void" is normally only good for async event handler
async void buttonTest_Click(object sender, EventArgs e)
{
try
{
var task = DownloadStringAsync("http://example.com"); // for example
// Wrong: task.Wait();
await task;
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
On a side note, now you've got other things to worry about. The UI is not blocked any more, while the asynchronous operation is still in progress. So, your user may click the Test
button again, and you're suddenly having two pending async operations. You should account for such scenario (it's been widely discussed here on SO as well).
Upvotes: 1