应用程序生命周期事件的异步方法(例如Application_Closing)

时间:2013-08-03 15:45:21

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

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

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

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

文章建议2种解决方法,似乎都不是理想的:

  1. 使用其他API,例如IsolatedStorage而不是StorageFolder / File,它支持同步操作。
  2. 随时随地保存与最后保存
  3. 我对(2)的问题在于,即使我尽快启动它,它仍然无法保证它有时间保存。

    我对(1)的问题是......呃...我使用的是ServiceLocator / IoC模式(我永远无法记住哪种模式是什么),所以这迫使我在接口中引入同步操作例如,ICachedDataProvider

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

3 个答案:

答案 0 :(得分:2)

  

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

不幸的是,没有。您可以采用各种方法来包装这些方法,但它们都不是万无一失的。 This blog entry描述了各种方法。在你的情况下,我建议卸载到另一个线程;它是最容易上班的,但只有在ICachedDataProvider是线程安全时才会起作用。

答案 1 :(得分:1)

我找到了似乎的东西,但是我会让这个问题等待一段时间等待反馈或其他解决方案。

我将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();
}

答案 2 :(得分:0)

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

但是......这是一个权宜之计。一旦启动关闭或停用操作,就没有任何东西可以阻止它发生,没有任何东西可以打败开始的“死亡时钟”。期。值得注意的是,这同样适用于Windows应用商店应用中的Suspensions。没有“购买更多时间”的机制--Windows Store Apps确实提供了“叛徒”,但正如我在帖子中提到的,那些仍然在上述“死亡时钟”的约束下运行。

我提出这个问题是因为你提到了:

  

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

当我读到这个问题时,也许它表明应用程序启动“随你随地”操作的情况,然后在保存运行时,会发生生命周期事件(关闭/停用)......这些生命周期事件将是对正在进行的保存的幸福无知,应用程序将放弃执行,事情将简单地扼杀到一个非礼貌的停止。在这种情况下,保存操作可以包括同步标志以指示操作正在进行中,然后可以在生命事件内部观察,但是(冒着击败死马的风险)你仍然需要意识到整个“死亡时钟”的事情(加上事情开始变得复杂/错综复杂。)

最终,如果您的应用发现自己处于豁免可能需要的时间超过允许时间的情况下,重新考虑游戏中的确切机制可能很重要,看看是否有某种方法可以避免这种情况。虽然有很多方法可以在此到期时间内“玩弄”异步,但会到期。