3

C /XAMLのWindows8アプリケーションの場合、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メソッドから、データを適切に保存します(ただし、明らかにアプリを閉じることはありません...)。問題は、アプリケーションが一時停止しているときに時間がなくなることだと思います。このスレッドの問題のように見えます:App.OnSuspendingから呼び出されると、StorageFolder.CreateFileAsyncがクラッシュします。しかし、私はこの質問のすべての解決策を試しましたが、まだ問題があります...

4

2 に答える 2

10

問題は、Completeすべてのasync操作が完了する前に電話をかけていることです。

最も簡単な解決策は、の代わりにメソッドを作成し、それをで作成SaveItemすることです。async Taskasync voidawaitBeforeClosing

原則として、asyncメソッドは、返す必要がない限り、常にTask/を返す必要があります(イベントハンドラーなど)。Task<T>void

于 2012-08-31T11:04:57.920 に答える
7

短く驚くべき答えは、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は信頼できないため、できるだけ頻繁に、そして頻繁に保存する必要があるということです。

于 2013-01-22T17:06:52.043 に答える