我正在编写一个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 !!!!!");
}
从未打印停用!!!
答案 0 :(得分:7)
问题在于await
关键字。简而言之,await
确实不会阻止执行线程,因为它可能听起来。恰恰相反,当执行到await
关键字时,从调用者的角度来看,它看起来像return
。与await
关联的任务完成后,计划在稍后运行继续(await
关键字之后)。有关详细信息,建议您详细了解await
和任务,例如here。
在您的情况下,当调用Deactivated或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_Deactivated时,您的应用程序将被视为已准备好关闭。但实际上还没准备好,因为await writer.WriteAsync(data);
可能还没有开始。这就是为什么你的应用程序关闭而不写任何东西。
顺便说一句,如果您的应用在停用期间没有进行逻辑删除,就像您快速返回它一样,WriteAsync
最终应该完成。但当然这不是你所期望的。
为了解决这个问题,您需要同步运行文件写操作。顺便说一句,这正是旧API所做的,这就是它的工作原理。解决问题的最简单方法是将CacheData
函数更改为Task
而不是void
(至public 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();
}
处理程序。像这样:
{{1}}
答案 1 :(得分: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();
}