【问题标题】:Async method on Application lifecycle events (e.g. Application_Closing)应用程序生命周期事件的异步方法(例如 Application_Closing)
【发布时间】:2023-03-24 11:03:02
【问题描述】:

我正在尝试在应用关闭/停用时保存应用数据。 在 WP8 中我使用了 StorageFile,它只支持 Async 方法。

问题是(正如我在阅读this article 时怀疑并确认的那样),简单地说,操作系统生命周期事件和异步方法不能很好地混合在一起。所以,这不起作用(即使没有 async/await)

private async void Application_Deactivated(object sender, DeactivatedEventArgs e)
{
     var dataSvc = SimpleIoc.Default.GetInstance<ICachedDataService>();
     await dataSvc.StoreCachedDataAsync();
}

文章提出了 2 种解决方法,但似乎都不理想:

  1. 使用不同的 API,例如隔离存储而不是 StorageFolder/File,后者支持同步操作。
  2. 随用随保存与最终保存

我对 (2) 的问题是,即使我尽快启动它,它仍然不能保证它有时间保存。

我对 (1) 的问题是……嗯……我正在使用 ServiceLocator/IoC 模式(我不记得哪个模式是什么),所以这迫使我在 @ 的接口中引入同步操作例如 987654323@。

还有其他方法吗?是否可以将 Async 方法转换为同步方法以增加代码重用?

【问题讨论】:

    标签: c# windows-phone-8 async-await


    【解决方案1】:

    是否可以将 Async 方法转换为同步方法以增加代码重用?

    很遗憾,没有。您可以采取多种方法来包装这些方法,但它们都不是万无一失的。 This blog entry 描述了各种方法。在你的情况下,我建议卸载到另一个线程;这是最容易开始工作的,但只有在 ICachedDataProvider 是线程安全的情况下才能工作。

    【讨论】:

    • "此博客条目" => 403 禁止
    • MS 更改了他们所有的博客网址,并没有转发旧的……不过,有一个 more exhaustive article 可用。
    【解决方案2】:

    我发现了一些似乎可行的方法,但我将让这个问题搁置一段时间以等待反馈或其他解决方案。

    我将 Application_Closing 和 Application_Deactivated 修改为以下(基于this SO question

    private void Application_Deactivated(object sender, DeactivatedEventArgs e)
    {
         var dataSvc = SimpleIoc.Default.GetInstance<ICachedDataService>();
         var task = Task.Run(async () => { await dataSvc.StoreCachedDataAsync(); });
         task.Wait();
    }
    

    【讨论】:

    • 这是我在回答中推荐的“卸载到另一个线程”选项。如果您的ICachedDataService 是线程安全的,这是最简单的解决方案。
    • @StephenCleary,啊......太好了......在发布我的答案之前我没有看到你的答案。
    【解决方案3】:

    感谢您的引用。如您所见,可以选择包装/启动任务并尝试同步等待其完成。

    但是……这充其量只是权宜之计。一旦启动关闭或停用操作,没有什么可以阻止它的发生,也没有什么可以打败开始的“死亡时钟”。时期。值得注意的是,这同样适用于 Windows 应用商店应用程序中的暂停。没有“购买更多时间”的机制 - Windows 应用商店应用确实提供“延期”,但正如我在帖子中提到的,这些仍然在上述“死亡时钟”的约束内运行。

    我提出这个是因为你提到:

    我对 (2) 的问题是它仍然不能保证它会 即使我尽快启动它也有时间保存。

    当我读到这个问题时,也许它表明应用程序开始“随时保存”操作,然后在保存运行时发生生命周期事件(关闭/停用)......这些生命周期事件将幸福地忽略正在进行的保存,应用程序将放弃其执行,事情将简单地磨成不礼貌的停止。在这种情况下,保存操作可能包含一个同步标志,以指示该操作正在进行中,然后可以在生命周期事件中对其进行监视,但是(冒着打死马的风险)您仍然需要意识到整个“死亡时钟”的事情(加上事情开始变得复杂/令人费解。)

    最终,如果您的应用发现自己的保存时间可能比允许的时间长,那么重新考虑具体的机制并首先看看是否有某种方法可以避免这种情况可能很重要。尽管有很多方法可以在这个过期时间内“玩弄”异步,但过期还是会发生。

    【讨论】:

    • 我不太关心 (2) 中的死亡时钟,因为我在操作系统生命周期事件发生时运行异步操作。是的,如果允许的时间不够,您需要重新考虑您的应用,并且可能需要后台任务(或其他)
    猜你喜欢
    • 1970-01-01
    • 2020-05-10
    • 1970-01-01
    • 2015-06-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多