【问题标题】:Async calls in Prism.FormsPrism.Forms 中的异步调用
【发布时间】:2017-07-12 04:18:46
【问题描述】:

我想在 Xamarin 应用程序的不同位置调用一些异步服务。我使用 Prism 从本机 UWP 应用程序移植我的代码。

前段时间我可以通过声明像

这样的方法来做到这一点
protected override void OnInitialized()

public override async void OnNavigatedTo(NavigationParameters parameters)

在那里使用等待。但是,它停止了工作。

尝试使用 GetAwaiter().GetResult() 会阻塞执行并导致死锁。

考虑到 INavigationService.NavigateAsync 本身就是异步方法,这有点奇怪,但示例建议在 OnInitialized 中使用而不需要任何等待,我认为这是错误的。

那么,有没有人建议如何在 Prism.Forms 中正确进行异步调用?

【问题讨论】:

    标签: asynchronous xamarin async-await prism


    【解决方案1】:

    OnNavigatedTo 从 UI 线程调用(它是 UI 生命周期的一部分)。如果你在那个方法内部阻塞,你当然会遇到死锁。

    仅仅因为 NavigateAsync 返回一个 Task 并具有异步名称,并不意味着该方法中的所有内容都发生在另一个线程上。它只是意味着它通常会做一些你可以等待的事情。

    这里的问题是,OnNavigatedTo 正在返回 void,所以一旦你在那里等待,它将返回给调用者。这并不能阻止您使用它,您只是不能在此阻止

    public override async void OnNavigatedTo(NavigationParameters parameters)
    {
        // do sync stuff
        await DoSomethingAsync();
        // this happens after all the other lifecycle methods
    }
    

    请注意,等待之后的所有事情都会在整个导航完成之后发生。并且在那里抛出的异常不会出现(基本上就是一劳永逸)。

    您始终可以通过不使用 async/await 而是使用 .ContinueWith(...) 来明确延续。

    【讨论】:

    • 这正是我之前的工作方式。但是我几个月没有接触Android部分,也许通过nugget进行了几次升级,现在你描述的方式给了我未处理的异常。具体来说,我使用 SQLite,当我等待异步代码时它会中断。当我用同步调用替换完全相同的行时,它可以工作。
    • 还有一件事,这种方法在 UWP 应用程序中适用于我,我遇到问题的是 Xamarin。
    • 究竟有哪些例外?这主要是由于在某个地方调用了 Task.Result,你几乎不应该这样做。
    • 它崩溃得太厉害了,我什至无法捕捉到异常。在我更新到最新版本的 SQLite 后,OnNavigatedTo 的问题似乎消失了,不知道它是否相关,但我仍然对 PrismApplication.OnInitialized 有问题。它在那里惨遭坠毁,甚至没有发现异常。目前我通过在新线程中启动这个东西找到了解决方案,所以我所做的是:TaskFactory.StartNew(()=> { try { ().GetAwaiter().GetResult(); } catch (异常 ex) { ... 处理异常 } } 这段代码成功了。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-06-23
    • 2019-02-24
    • 2021-07-18
    • 2017-08-24
    • 1970-01-01
    相关资源
    最近更新 更多