使用Task.Wait()处理后台文件传输

时间:2014-01-07 07:05:49

标签: c# .net windows-phone-8 backgroundworker async-await

我正在使用基于事件的第三方库。我真的只对调用库方法感兴趣并知道库何时完成。非常像这里:Convert Event based pattern to async CTP pattern

问题是图书馆似乎使用Windows Phone的Background File Transfer来完成它的工作。

我的症状是,只有在Task.Wait(TimeSpan.FromSeconds(5))超时后才会调用库的完成处理程序。

我试图在ThreadPool中搜索一些关于运行后台文件传输的文档(正如我在异步代码中所假设的那样,这是库运行的地方),但实际上找不到任何信息。那么我的问题(仅在超时后调用完成处理程序)是否应该在ThreadPool中运行后台文件传输代码?

任何想法对这类问题有什么好处?

1 个答案:

答案 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上广泛讨论过)。