Debugging UWP使用释放模式丢失序列化数据

Debugging UWP使用释放模式丢失序列化数据,debugging,uwp,release,Debugging,Uwp,Release,我正在尝试使用VisualStudioCommunity2015在UWP中制作一个日记应用程序。因此,所有日记条目都保存在一个ObservableCollection(类型为DiaryEntry,有三个字符串)中。在应用程序类I的onSuspend方法中,序列化(使用XmlSerializer)并将ObservableCollection保存到应用程序的LocalFolder。在App类的OnLaunched方法中,我反序列化了数据,并将其再次放入ObservableCollection中 当我

我正在尝试使用VisualStudioCommunity2015在UWP中制作一个日记应用程序。因此,所有日记条目都保存在一个ObservableCollection(类型为DiaryEntry,有三个字符串)中。在应用程序类I的onSuspend方法中,序列化(使用XmlSerializer)并将ObservableCollection保存到应用程序的LocalFolder。在App类的OnLaunched方法中,我反序列化了数据,并将其再次放入ObservableCollection中

当我在调试模式下运行此应用程序时,它每次都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;
    }
私有异步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包在这里=>