【问题标题】:Saving data during the OnSuspending method在 OnSuspending 方法期间保存数据
【发布时间】:2012-08-31 09:45:12
【问题描述】:

对于 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<LoadingProgress>(fileNameLoadingProgress, InitLoading);
    }


    public static async void SaveItem<T>(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<T>(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 方法中,它可以很好地保存数据(但永远不要关闭应用程序......)。我真的认为问题在于应用程序暂停时我的时间用完了。看起来确实像这个线程上的问题:StorageFolder.CreateFileAsync crashes when called from App.OnSuspending。但是我已经尝试了这个问题的所有解决方案,但我仍然有问题......

【问题讨论】:

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


    【解决方案1】:

    您的问题是您在所有 async 操作完成之前调用了 Complete

    最简单的解决方案是将SaveItem 设为async Task 方法而不是async void,然后将await 设为BeforeClosing

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

    【讨论】:

    • 非常感谢。我很奇怪地认为,如果一个方法是异步的,它将使用 await 一词异步执行,但我忘记了 Task 变量的使用......
    【解决方案2】:

    简短而令人惊讶的答案是 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 是不可靠的。

    【讨论】:

      猜你喜欢
      • 2018-05-25
      • 2015-10-01
      • 2020-12-11
      • 1970-01-01
      • 2011-12-22
      • 1970-01-01
      • 2015-01-25
      • 2016-08-17
      • 1970-01-01
      相关资源
      最近更新 更多