【问题标题】:How to wait for async method to return?如何等待异步方法返回?
【发布时间】:2013-07-24 14:49:10
【问题描述】:

我正在尝试创建一个应用,它使用单点登录和实时连接并根据用户的实时连接信息自动注册用户。

当我的应用程序启动时,我调用我的 LiveConnectViewModel 并调用这两个函数:

        public async void AuthInitialize() 
    {
        string[] scopes = new[] { "wl.signin", "wl.basic", "wl.photos", "wl.emails", "wl.skydrive" };

        liveAuthClient = new LiveAuthClient();
        LiveLoginResult liveLoginResult = await liveAuthClient.InitializeAsync(scopes);

        if (liveLoginResult.Status == LiveConnectSessionStatus.Connected)
        {
            App.Session = liveLoginResult.Session;
        }
        else 
        {
            liveLoginResult = await liveAuthClient.LoginAsync(scopes);
            App.Session = liveLoginResult.Session;
        }
        await LoadProfileAsync();
    }

    public async Task LoadProfileAsync() 
    {
        LiveConnectClient client = new LiveConnectClient(App.Session);
        LiveOperationResult liveOperationResult = await client.GetAsync("me");
        LiveOperationResult liveOperationResultPicture = await client.GetAsync("me/picture");
        dynamic dynResult = liveOperationResult.Result;
        dynResult.picture = liveOperationResultPicture.Result;
        User currentUser = await UserViewModel.findOrCreateUserAsync(dynResult);
        App.currentUser = currentUser;
    }

当初始屏幕消失并且我的视图出现时,立即调用另一个方法。

执行该代码:

        public ProfilePageViewModel()
    {
        this.CurrentUser = App.currentUser;
    }

现在我的总体问题是这里的时机。当我调试我的应用程序时,我可以看到我的 LiveConnectViewModel 被首先调用并进行初始连接,然后 LoadProfileAsync 被执行,直到我的程序到达第一个 await 语句。

当达到这一点时,我的应用程序立即停止处理此调用并继续运行。现在,当涉及到我的 ProfilePageViewModel 并且它应该设置我的“CurrentUser”属性时,await 仍然没有将我的用户返回到我的 App.CurrentUser 属性,这就是它说它为 null 的原因。

通常我会等到 App.CurrentUser 属性设置为 null 以外的其他值,但我无法摆脱一种奇怪的感觉,我要么错过了正确实现 MVVM 模式,要么我做了一些非常错误的事情使用等待和异步...

谁能帮我澄清这种行为?

【问题讨论】:

  • 从对 LoadProfileAsync() 的调用前面删除 awaitawaiting 已经在 LoadProfileAsync() 中完成。
  • 反之亦然,如果这更适合您的业务需求。没有必要等待两次,这样做只会使事情变得混乱。

标签: c# mvvm asynchronous async-await


【解决方案1】:

你应该avoid async void, as I describe in a recent MSDN article

一旦你让AuthInitializeAsync返回Task而不是void,那么你可以在创建你的视图模型之前await它。

【讨论】:

  • 嗨,斯蒂芬,感谢您的回答。我已经在 stackoverflow 上的另一篇文章中阅读了您的 MSDN 文章。我的问题是,如果我将返回类型更改为 Task 我无法在我的构造函数中正确调用此函数(这就是我实际正在做的事情)。有什么办法可以让它在我的构造函数中仍然有效?
  • 我在async constructors 上有一个博客条目。在我的 MVVM 项目中,我使用 async 工厂方法遵循 VM-first 模式。但是,如果您使用的是 IoC 或 V-first 模式,那么您需要使用我的博客中描述的异步初始化模式。
猜你喜欢
  • 2017-09-24
  • 2013-02-14
  • 1970-01-01
  • 2021-10-06
  • 2020-03-13
  • 1970-01-01
  • 2019-03-20
  • 2021-11-01
  • 1970-01-01
相关资源
最近更新 更多