在OnSuspending方法中保存数据

对于C / XAML中的Windows 8应用程序,我必须将一些数据存储到LocalState文件夹中。 我认为使用async / await运算符时遇到了一些麻烦。

当我在应用程序运行时保存数据时,一切正常,但是当我尝试在OnSuspending方法中保存数据时,似乎我的应用程序不会等待我的保存方法完成以暂停应用程序。

更奇怪的是,当我调试并逐步完成所有操作时,一切正常,但是当我没有设置任何断点时,应用程序在保存数据之前关闭。

这是我的代码:

private async void OnSuspending(object sender, SuspendingEventArgs e) { var deferral = e.SuspendingOperation.GetDeferral(); await api.BeforeClosing(true); deferral.Complete(); } public async Task BeforeClosing(Boolean toTombstoning) { SaveItem(fileNameLoadingProgress, InitLoading); } public static async void SaveItem(String fileName, T data, Boolean crossThreadSecure = false) where T : IBinarySerializable { await CreateNewStorageFile(fileName); StorageFolder localFolder = Windows.Storage.ApplicationData.Current.LocalFolder; StorageFolder dataFolder = await localFolder.GetFolderAsync("Data"); StorageFile file = await dataFolder.GetFileAsync(fileName); using (var stream = await file.OpenStreamForWriteAsync()) { using (var writer = new BinaryWriter(stream)) { writer.Write(data); } } } public async static Task CreateNewStorageFile(string filename) { StorageFolder localFolder = Windows.Storage.ApplicationData.Current.LocalFolder; StorageFolder dataFolder = await localFolder.CreateFolderAsync("Data", CreationCollisionOption.OpenIfExists); storage = await dataFolder.CreateFileAsync(filename, CreationCollisionOption.OpenIfExists); } 

我是否在使用await运算符? 或者,在暂停申请之前我们可以进行一些操作的最长时间是多少?

谢谢

编辑:我做了一些新的测试:如果我删除deferral.Complete(); 从OnSuspending方法,它可以很好地保存数据(但从未明显关闭应用程序……)。 我真的认为问题是当应用程序挂起时我没时间了。 它看起来像这个线程上的问题: 从App.OnSuspending调用时,StorageFolder.CreateFileAsync崩溃 。 但我已经尝试了这个问题的所有解决方案,我仍然有问题……

您的问题是,在Complete所有async操作之前,您正在调用Complete

最简单的解决方案是使SaveItem成为async Task方法而不是async void ,然后在BeforeClosing await它。

作为一般规则, async方法应始终返回Task / Task除非它们必须返回void (例如,事件处理程序)。

简短且令人惊讶的答案是OnSuspending对于任何应用程序关键持久性逻辑来说都是一个不可靠的地方。 出于某种原因,Microsoft决定在应用程序关闭后将OnSuspending事件延迟5-10秒。 如果在此事件之前重新启动应用程序,则会生成一个单独的应用程序实例,并且它不知道仍处于挂起过程中的应用程序。

在WinRT应用程序数据示例项目中看起来非常简单的示例出现问题后,我得出了这个结论: http : //code.msdn.microsoft.com/windowsapps/ApplicationData-sample-fb043eb2 。 经过一番挫折之后,我在MSDN上发现了一个讨论OnSuspending作为保存触发器的线程: http ://social.msdn.microsoft.com/Forums/en-US/winappswithcsharp/thread/43da2212-9910-461d-816a-94b479ce9885/ 。 这个主题的要点是你应该尽可能频繁地保存,因为OnSuspending是不可靠的。