我正在使用基于事件的第三方库。我真的只对调用库方法感兴趣并知道库何时完成。非常像这里:Convert Event based pattern to async CTP pattern
问题是图书馆似乎使用Windows Phone的Background File Transfer
来完成它的工作。
我的症状是,只有在Task.Wait(TimeSpan.FromSeconds(5))超时后才会调用库的完成处理程序。
我试图在ThreadPool中搜索一些关于运行后台文件传输的文档(正如我在异步代码中所假设的那样,这是库运行的地方),但实际上找不到任何信息。那么我的问题(仅在超时后调用完成处理程序)是否应该在ThreadPool中运行后台文件传输代码?
任何想法对这类问题有什么好处?
答案 0 :(得分:1)
您链接的模式是正确的。它不使用async/await
,但也不使用Task.Wait()
。它返回一个Task
对象,并且异步地对该任务进行await
。这意味着,当任务到达完成(故障,取消)状态时,任务计划程序将异步调用await task
之后的代码。
否则,您正在使用同步Task.Wait()
调用阻止UI线程及其消息泵,因此完成事件没有机会被正确触发。
要更好地理解这个问题,请阅读以下内容:Don't Block on Async。
要纠正您的代码,您必须创建整个调用链async
,直到根,在UI应用程序中通常是一个事件处理程序。 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);
}
}
另一方面,现在您还有其他需要担心的事情。 UI不再被阻止,异步操作仍在进行中。因此,您的用户可能会再次单击Test
按钮,并且您突然有两个待处理的异步操作。你应该考虑到这种情况(它也在SO上广泛讨论过)。