Debugging UWP使用释放模式丢失序列化数据
我正在尝试使用VisualStudioCommunity2015在UWP中制作一个日记应用程序。因此,所有日记条目都保存在一个ObservableCollection(类型为DiaryEntry,有三个字符串)中。在应用程序类I的onSuspend方法中,序列化(使用XmlSerializer)并将ObservableCollection保存到应用程序的LocalFolder。在App类的OnLaunched方法中,我反序列化了数据,并将其再次放入ObservableCollection中 当我在调试模式下运行此应用程序时,它每次都100%工作,但在发布模式下,一旦我关闭并再次打开应用程序,我将丢失ObservableCollection。其他时候它工作一两次,但我仍然丢失数据。我想知道的是如何让我的应用程序在发布模式下工作 以下是我正在使用的方法:Debugging UWP使用释放模式丢失序列化数据,debugging,uwp,release,Debugging,Uwp,Release,我正在尝试使用VisualStudioCommunity2015在UWP中制作一个日记应用程序。因此,所有日记条目都保存在一个ObservableCollection(类型为DiaryEntry,有三个字符串)中。在应用程序类I的onSuspend方法中,序列化(使用XmlSerializer)并将ObservableCollection保存到应用程序的LocalFolder。在App类的OnLaunched方法中,我反序列化了数据,并将其再次放入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;
}
私有异步void SaveCollection(字符串xml)
{
//序列化observablecollection并将其保存到本地文件夹
StorageFile sf=等待ApplicationData.Current.LocalFolder.CreateFileAsync(“Diary.txt”,CreationCollisionOption.ReplaceExisting);
等待Windows.Storage.FileIO.WriteTextAsync(sf,xml);
}
专用异步任务GetSavedCollection()
{
尝试
{
Windows.Storage.StorageFolder StorageFolder=Windows.Storage.ApplicationData.Current.LocalFolder;
Windows.Storage.StorageFile sampleFile=wait-storageFolder.GetFileAsync(“Diary.txt”);
string text=wait Windows.Storage.FileIO.ReadTextAsync(sampleFile);
返回文本;
}
catch(filenotfounde异常)
{
返回“”;
}
}
公共静态字符串ToXml(ObservableCollection d)
{
XmlSerializer serializer=新的XmlSerializer(typeof(observeCollection));
StringBuilder StringBuilder=新的StringBuilder();
XmlWriterSettings=新的XmlWriterSettings()
{
缩进=真,
OmitXmlDeclaration=true,
};
使用(XmlWriter=XmlWriter.Create(stringBuilder,设置))
{
serializer.Serialize(xmlWriter,d);
}
返回stringBuilder.ToString();
}
//从xml反序列化
公共静态ObservableCollection FromXml(字符串xml)
{
如果(xml==“”)
{
返回新的ObservableCollection();
}
XmlSerializer serializer=新的XmlSerializer(typeof(observeCollection));
可观测采集值;
使用(StringReader StringReader=new StringReader(xml))
{
对象反序列化=序列化程序。反序列化(stringReader);
值=(ObservableCollection)反序列化;
}
返回值;
}
我这样称呼这些方法:
日记=FromXml(等待GetSavedCollection())
储蓄收集(ToXml(日记)) 如果不完整地重新编写代码(请参阅),很难说清楚,但我怀疑这与对应用程序生命周期的误解有关,也与您将代码添加到
OnLaunched
和OnSuspending
方法的原因有关
要了解生命周期,请参阅和
现在这些方法
让我们先来处理暂停时的问题,因为这更简单。您的代码应该如下所示:
private void OnSuspending(object sender, SuspendingEventArgs e)
{
var deferral = e.SuspendingOperation.GetDeferral();
SaveCollection(ToXml(Diaries));
deferral.Complete();
}
if (e.PreviousExecutionState == ApplicationExecutionState.Terminated)
{
//TODO: Load state from previously suspended application
Diaries = FromXml(await GetSavedCollection());
}
请注意,如果在deleral.Complete()之后调用SaveCollection
代码>在应用程序终止之前,它可能无法完成,这可能是未完成的原因
OnLaunching
方法更复杂。我怀疑您有这样的代码:
private void OnSuspending(object sender, SuspendingEventArgs e)
{
var deferral = e.SuspendingOperation.GetDeferral();
SaveCollection(ToXml(Diaries));
deferral.Complete();
}
if (e.PreviousExecutionState == ApplicationExecutionState.Terminated)
{
//TODO: Load state from previously suspended application
Diaries = FromXml(await GetSavedCollection());
}
根据模板中的TODO注释,这似乎是合乎逻辑的做法,但不适合您希望在重新启动应用程序时始终从磁盘加载的场景。例如,当用户先前关闭应用程序时,上述内容不会加载。我想你也会想载入日记的。(因为您没有提供完整的复制步骤,所以我无法确切地知道您是如何测试和重新创建所看到的行为的。)
相反,如果需要,在预启动激活之前加载日志
if (Diaries == null)
{
Diaries = FromXml(await GetSavedCollection());
}
if (e.PrelaunchActivated == false)
或
这是一个如何定义和调用SaveCollection
的问题
您已将SaveCollection
定义为async void
。这很糟糕。唯一应该是async void
的是事件处理程序。您应该将其定义为async Task
,并等待对其的调用:
private async Task SaveCollection(string xml)
{
System.Diagnostics.Debug.WriteLine(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);
}
await SaveCollection(ToXml(Diaries));
如果不等待此呼叫,它可能无法正确完成。这种行为在.NetNative编译下更为明显,这一点我并不感到惊讶
或者这可能是两个问题的组合。在保存数据过程中尝试写入一些日志。您使用哪个NETCore.universalwindowsform
?尽量达到最高点。(5.3.1). 此问题可能与.NET本机工具链有关。如果在应用程序的生成配置中启用了.NET本机工具链
选项,则使用Microsoft.NETNative.Analyzer
。因此,您可以看到与编译器不兼容的代码。NuGet包在这里=>