从哪里调用异步方法?

时间:2015-06-04 21:24:25

标签: c# file-io windows-runtime async-await win-universal-app

我在调用异步方法时遇到了一些麻烦。该方法在类中并加载文本文件。我想在应用程序启动时加载文本文件。但是,我无法从构造函数中调用异步方法。我在网上看过的大多数例子都经常从异步按钮事件中调用方法。

目前,我正在尝试使用构造函数:

Task.Run(async () =>
{
    this.categories = await GenerateCategories(numberOfCategories);
});

虽然这样可行但是在调用此方法之后程序的其余部分仍然继续,并且使用“类别”的代码执行会导致崩溃(因为类别仍为空,因为任务尚未完成)。

总而言之,从哪里以及如何最好地调用此方法?当用户按下按钮或任何东西时,我不希望它加载,并且我希望在执行任何更多代码之前填充“类别”。

我正在使用C#并编写通用应用程序,因此加载文件必须是异步的。

2 个答案:

答案 0 :(得分:5)

我的博客上有关于using async in "impossible" situations的系列文章;一篇文章特别涵盖async constructors

由于您正在编写通用应用程序,因此要记住的重要一点是用户界面必须最初立即显示(同步);在初始视图显示之前执行异步工作根本不是一个选项。相反,您应该(同步)初始化/构造为“加载”状态,然后在加载文件时更新您的UI。

我有three-part series of MSDN articles on asynchronous patterns for MVVM applications,您可能会觉得有帮助。

答案 1 :(得分:1)

简单的答案是Task.Run()返回一个任务。如果在任务上调用.Wait()方法,则线程将暂停,直到任务完成并且设置了类别成员。

然而,这忽略了该方法可能由于某种原因而创建为异步。您可能不希望绑定您的UI线程Wait()以完成异步方法。您可能还需要关注Task.Run的手册页上的这个注释:

  

语言编译器使用Run(Func)方法来支持   async和await关键字。它不打算直接调用   来自用户代码。

相反,您可以创建一个异步void方法,以便从将在后台线程中异步运行任务的构造函数进行调用。您应该确保所有依赖于GenerateCategories运行的逻辑都是从该方法运行的。

要正确使用异步方法,必须将其控制流与主用户界面线程分离。当任务需要通知UI其进度时,您可以使用Control.Invoke将任务内的消息发送到UI。

相关问题