C# 在OnSuspending方法期间保存数据

C# 在OnSuspending方法期间保存数据,c#,windows-8,windows-runtime,async-await,C#,Windows 8,Windows Runtime,Async Await,对于C/XAML中的Windows8应用程序,我必须将一些数据存储到LocalState文件夹中。我想我在使用async/await操作符时遇到了一些问题 当我在应用程序运行时保存数据时,一切正常,但当我尝试在OnSuspend方法期间保存数据时,应用程序似乎不会等待我的保存方法完成后挂起应用程序 奇怪的是,当我一步一步地调试和执行所有操作时,一切都很好,但当我没有设置任何断点时,应用程序会在数据保存之前关闭 这是我的密码: private async void OnSuspending

对于C/XAML中的Windows8应用程序,我必须将一些数据存储到LocalState文件夹中。我想我在使用async/await操作符时遇到了一些问题

当我在应用程序运行时保存数据时,一切正常,但当我尝试在OnSuspend方法期间保存数据时,应用程序似乎不会等待我的保存方法完成后挂起应用程序

奇怪的是,当我一步一步地调试和执行所有操作时,一切都很好,但当我没有设置任何断点时,应用程序会在数据保存之前关闭

这是我的密码:

    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);
    }
private async void OnSuspending(对象发送方,SuspendingEventArgs e)
{
var deleral=e.SuspendingOperation.getdeleral();
在关闭前等待api(真);
延迟。完成();
}
关闭前的公共异步任务(Boolean ToToToMbsting)
{
保存项(fileNameLoadingProgress,InitLoading);
}
公共静态异步void SaveItem(字符串文件名,T数据,布尔crossThreadSecure=false),其中T:IBinarySerializable
{
等待CreateNewsStorage文件(文件名);
StorageFolder localFolder=Windows.Storage.ApplicationData.Current.localFolder;
StorageFolder dataFolder=等待localFolder.GetFolderAsync(“数据”);
StorageFile file=wait dataFolder.GetFileAsync(文件名);
使用(var stream=await file.OpenStreamForWriteAsync())
{
使用(var writer=newbinarywriter(流))
{
writer.Write(数据);
}
}
}
公共异步静态任务CreateNewsStorage文件(字符串文件名)
{
StorageFolder localFolder=Windows.Storage.ApplicationData.Current.localFolder;
StorageFolder dataFolder=等待localFolder.CreateFolderAsync(“数据”,CreationCollisionOption.OpenIfExists);
存储=等待dataFolder.CreateFileAsync(文件名,CreationCollisionOption.OpenIfExists);
}
我是不是对等待接线员做了什么错事?或者,在挂起应用程序之前,我们可以执行某些操作的时间是否最长

多谢各位


编辑:我做了一些新的测试:如果我删除deleral.Complete();通过OnSuspending方法,它可以很好地保存数据(但永远不会关闭应用程序…)。我真的认为问题在于,当应用程序挂起时,我没有时间了。看起来此线程上确实存在问题:。但是我已经尝试了这个问题的所有解决方案,但我仍然有问题…

您的问题是,在所有
异步
操作完成之前,您正在调用
Complete

最简单的解决方案是将
SaveItem
设置为
async Task
方法,而不是
async void
,然后
在关闭之前在
中等待它


一般来说,
async
方法应该总是返回
Task
/
Task
,除非它们必须返回
void
(例如,事件处理程序)。

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

在WinRT应用程序数据示例项目中,我遇到了以下看似非常简单的示例的问题后得出了这个结论:。在经历了一些挫折之后,我在MSDN上找到了一个讨论OnSuspend作为保存触发器的线程:
. 此线程的要点是,您应该尽可能频繁地保存,因为onsuspend是不可靠的

多谢各位。我惊讶地认为,如果一个方法是异步的,它将使用wait这个词异步执行,但我忘记了Task变量的用法。。。