1

WP8 アプリを作成していますが、アプリが非アクティブ化または閉じられたときにデータを保存したいと考えています。

新しい WinRT API を試しましたが、アプリが非アクティブ化されている間は機能しません :|

コード:

 public async Task CacheData()
        {

            StorageFolder localFolder = ApplicationData.Current.LocalFolder;

                string data = "Hello!";

                ///WinRT not Working !!!

                // Get a reference to the Local Folder 
                // Create the file in the local folder, or if it already exists, just replace it 

                StorageFile storageFileIsolated = await localFolder.CreateFileAsync("Data.data", CreationCollisionOption.ReplaceExisting);
                Stream writeStream = await storageFileIsolated.OpenStreamForWriteAsync();
                using (StreamWriter writer = new StreamWriter(writeStream))
                {
                    await writer.WriteAsync(data);
                }
            }
        }

しかし、古いAPIでうまく動作します

                string data = "Hello!";

                using (IsolatedStorageFile isf = IsolatedStorageFile.GetUserStoreForApplication())
                {
                    using (IsolatedStorageFileStream rawStream = isf.CreateFile("Data.store"))
                    {
                        StreamWriter writer = new StreamWriter(rawStream);
                        writer.WriteLine(data); // save the message
                        writer.Close();
                    }
                }

何が問題なのかわからない :| !!!

このコードでテストしました

 private  void Application_Deactivated(object sender, DeactivatedEventArgs e)
        {
            ViewModel.CacheExchangeRates().Wait();
            System.Diagnostics.Debug.WriteLine("deactivated !!!!!");
        }

非アクティブに印刷されたことはありません!!!

4

2 に答える 2

7

問題はawaitキーワードにあります。要するに、awaitそれが聞こえるかもしれないので、実際には実行中のスレッドをブロックしません。まったく逆に、awaitキーワードの実行に関してはreturn、発信者の観点からはそのように見えます。継続(awaitキーワードの後に​​続くもの)は、関連付けられたタスクawaitが完了したときに後で実行されるようにスケジュールされています。それについての詳細は、たとえばここawaitから始めて、タスクについてもっと読むことをお勧めします。

あなたの場合、DeactivateまたはClosingが呼び出されると、おそらく次のような呼び出しが行われます。

private void Application_Deactivated(object sender, DeactivatedEventArgs e)
{
    CacheData();
}

実行が最初のawaitキーワード(つまり、行StorageFile storageFileIsolated = await localFolder.CreateFileAsync("Data.data", CreationCollisionOption.ReplaceExisting);)になると、CacheData()メソッドは呼び出し元に制御を返します。他のすべては、そのタスクが完了すると、後で実行されます。しかし、あなたはあなたのApplication_Deactivated方法でそれを待っていません。代わりに、実行は続行され、制御は。を離れますApplication_Deactivated

コントロールがApplication_Deactivateを離れると、アプリはシャットダウンの準備ができていると見なされます。しかし、実際にはまだ準備ができawait writer.WriteAsync(data);ていません。おそらくまだ開始されていないからです。そのため、何も書かずにアプリが閉じます。

ところで、非アクティブ化中にアプリがトゥームストーンされていない場合は、すぐにアプリに戻ったかのように、WriteAsync最終的には完了する必要があります。しかしもちろん、それはあなたが期待するものではありません。

これを修正するには、ファイル書き込み操作を同期的に実行する必要があります。ちなみに、これはまさに古いAPIが行うことであり、それが機能する理由です。問題を解決する最も簡単な方法は、関数を(to )ではなくCacheDatareturnに変更し、ハンドラーで使用することです。このような:Taskvoidpublic async Task CacheData()Task.Wait()Application_Deactivated

public async Task CacheData()
    {

        StorageFolder localFolder = ApplicationData.Current.LocalFolder;

            string data = "Hello!";

            ///WinRT not Working !!!

            // Get a reference to the Local Folder 
            // Create the file in the local folder, or if it already exists, just replace it 

            StorageFile storageFileIsolated = await localFolder.CreateFileAsync("Data.data", CreationCollisionOption.ReplaceExisting);
            Stream writeStream = await storageFileIsolated.OpenStreamForWriteAsync();
            using (StreamWriter writer = new StreamWriter(writeStream))
            {
                await writer.WriteAsync(data);
            }            
    }

private void Application_Deactivated(object sender, DeactivatedEventArgs e)
{
    CacheData().Wait();
}
于 2013-02-18T13:09:59.320 に答える
2

同じ問題に遭遇し、次のように修正しました

StorageFile storageFileIsolated = localFolder.CreateFileAsync("Data.data", CreationCollisionOption.ReplaceExisting).AsTask().Result;
Stream writeStream = storageFileIsolated.OpenStreamForWriteAsync().Result;
using (StreamWriter writer = new StreamWriter(writeStream))
{
    writer.WriteAsync(data).Wait();
}
于 2014-04-20T22:55:54.613 に答える