我正在尝试在UWP中制作一个日记应用程序,所以所有的日记条目都保存在一个ObservableCollection中(类型为DiaryEntry,它有三个字符串)。在App类的OnSuspending方法中,我序列化(使用XmlSerializer)并将ObservableCollection保存到应用程序的LocalFolder中。在App类的OnLaunched方法中,我反序列化数据并将其放置在又是可观察的集合。
当我在调试模式下运行这个应用时,它每次都能100%正常工作,但在发布模式下,一旦我关闭并再次打开应用,ObservableCollection就会丢失。其他时候,它工作一两次,但我仍然会丢失数据。我想知道的是,如何才能让我的应用在发布模式下工作?
以下是我正在使用的方法:
private async void SaveCollection(string xml)
{
//Serializing our observablecollection and saving it to the local folder
StorageFile sf = await ApplicationData.Current.LocalFolder.CreateFileAsync("Diary.txt", CreationCollisionOption.ReplaceExisting);
await Windows.Storage.FileIO.WriteTextAsync(sf, xml);
}
private async Task<string> GetSavedCollection()
{
try
{
Windows.Storage.StorageFolder storageFolder = Windows.Storage.ApplicationData.Current.LocalFolder;
Windows.Storage.StorageFile sampleFile = await storageFolder.GetFileAsync("Diary.txt");
string text = await Windows.Storage.FileIO.ReadTextAsync(sampleFile);
return text;
}
catch (FileNotFoundException e)
{
return "";
}
}
public static string ToXml(ObservableCollection<DiaryEntry> d)
{
XmlSerializer serializer = new XmlSerializer(typeof(ObservableCollection<DiaryEntry>));
StringBuilder stringBuilder = new StringBuilder();
XmlWriterSettings settings = new XmlWriterSettings()
{
Indent = true,
OmitXmlDeclaration = true,
};
using (XmlWriter xmlWriter = XmlWriter.Create(stringBuilder, settings))
{
serializer.Serialize(xmlWriter, d);
}
return stringBuilder.ToString();
}
// Deserialize from xml
public static ObservableCollection<DiaryEntry> FromXml(string xml)
{
if (xml == "")
{
return new ObservableCollection<DiaryEntry>();
}
XmlSerializer serializer = new XmlSerializer(typeof(ObservableCollection<DiaryEntry>));
ObservableCollection<DiaryEntry> value;
using (StringReader stringReader = new StringReader(xml))
{
object deserialized = serializer.Deserialize(stringReader);
value = (ObservableCollection<DiaryEntry>)deserialized;
}
return value;
}
字符串
这是我如何调用这些方法的:
日志= FromXml(等待GetSavedCollection());
保存集合(到Xml(日志));
1条答案
按热度按时间4uqofj5v1#
我怀疑这是对应用程序生命周期的误解,以及您将代码添加到
OnLaunched
和OnSuspending
方法的地方。要了解生命周期,请参阅the docs here和this blog article。
现在这些方法。
让我们先处理
OnSuspending
,因为它更简单。您的代码应该如下所示:字符串
请注意,如果您在
deferral.Complete();
之后调用SaveCollection
,则在应用程序终止之前可能无法完成,这可能是导致没有OnLaunching
方法更复杂。我怀疑你有这样的代码:型
根据模板中的TODO注解,这似乎是合乎逻辑的做法,但对于您希望在重新启动应用程序时始终从磁盘加载的场景来说,这并不正确。当用户关闭应用程序时加载内容。我假设你也想加载日记条目。(因为你没有提供完整的再现步骤,我不知道你是如何测试和再现你所看到的行为的。
相反,如果需要的话,在
'PrelaunchActivated
检查之前加载日记。型
或者
这是一个如何定义和调用
SaveCollection
的问题。你已经将
SaveCollection
定义为async void
。这很糟糕。唯一应该是async void
的是事件处理程序。你应该将它定义为async Task
并等待对它的调用:型
如果不等待这个调用,它可能无法正确完成。这种行为在.NetNative编译下更明显,我不会感到惊讶。
或者这可能是两个问题的结合。