Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/314.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 确保数据反序列化/序列化_C#_Windows Phone 8.1 - Fatal编程技术网

C# 确保数据反序列化/序列化

C# 确保数据反序列化/序列化,c#,windows-phone-8.1,C#,Windows Phone 8.1,在我的ViewModel中,我有3个可观察集合,还有一个类,我在运行应用程序时加载它们。 为了确保observeablecollections被反序列化,我刚刚得到了 if(SomeCollection.Count == 0) ThisCollection = await deserializationMethod<ObservableColletion<T>>(filename); 这很好,没问题 我有一节课 if(ClassObject.Loaded != t

在我的
ViewModel
中,我有3个
可观察集合
,还有一个
,我在运行应用程序时加载它们。 为了确保
observeablecollections
被反序列化,我刚刚得到了

if(SomeCollection.Count == 0)
   ThisCollection = await deserializationMethod<ObservableColletion<T>>(filename);
这很好,没问题

我有一节课

if(ClassObject.Loaded != true)
   ThisObject = await deserializationMethod<T>(filename);
if(ClassObject.Loaded!=true)
ThisObject=等待反序列化方法(文件名);
我添加了一个属性-如果文件是反序列化的,那么它是真的。 它看起来有效,但实际上无效。这种情况很少发生,但有时文件未反序列化,当您使用应用程序时,该文件会被覆盖,因此所有数据都会被销毁。我找不到问题的原因。你只需运行一个应用程序,它就会发生——就像每100次运行一次

如何非常确定,若文件存在,那个么它肯定会被反序列化? 或者我应该把这些
可观察的集合
+
列成
列表
,并将其序列化为一个文件?这方面有什么好的做法吗

编辑:

我使用了
SemaphoreSlim
来确保一切都按预期使用,但今天又发生了

问题是,它发生在应用程序启动时,甚至没有其他任何东西被点击。现在不可能有什么东西在写。看起来数据未反序列化或未读取存在的文件。因为每次更改都是在关闭应用程序时写入的,所以一切都消失了。 还有其他想法吗?它可能是什么,或者如何确保数据被反序列化

编辑最终-复制问题:

我终于重现了正在发生的事情。因此,我删除了这里不需要的代码编辑

当用户返回或想要退出某个应用程序时(如果在
主页
),我需要处理
返回按钮
事件。
这部分代码显然是导致问题的原因。到底发生了什么。
首先,使用emulator不可能重现这个问题。
我的
BackPressed
方法包含wait和serialization方法,该方法保存了后来丢失的数据(正如Ondrej Svejdar所写,它是在读取之前写入的)。但我开始测试它,有奇怪的行为,我仍然有一些问题

它是如何发生的

当我启动了一个应用程序(例如,由于意外)并出现加载屏幕时,我开始点击后退按钮几次->应用程序没有运行,它正在尽快关闭,我甚至看不到UI(有时我能看到AppBar一会儿)。然后,当我再次尝试打开应用程序时(无论是立即打开还是稍后打开),它都在“恢复”,在这一刻之后,我的数据就消失了。但不是所有的数据。仅使用Wait in
BackPressed
方法保存的最后一个。只有这个。我试图保存一个、两个和三个
可观察集合
,无论有没有这个类,最后一个总是保存为“空”。在此等待之后,我得到了可能导致此问题的Application.Current.Exit()方法,但我不确定当序列化方法是Task并且只有最后一个被错误序列化时,这是否重要

当我从BackPressed方法中删除这个waitis时,我无法重现这个问题,所以就是这个问题


我还有一个问题:这种行为是预期的吗?是否有更好的方法关闭应用程序并确保序列化数据,或者我应该在使用应用程序时保存数据,而不是在退出应用程序时保存数据?

如果有人对如何正确操作感兴趣,我正在考虑并得出一些结论。 请记住,这是我的建议,可能有更好的方法

在处理BackPressedButton事件(硬件事件)时,我实现了返回到上一页(如果不在主页上)或离开应用程序(如果在主页上)。 我使用Application.Current.Exit()关闭了一个应用程序,这并没有造成问题(因为我保存的文件非常小),直到我开始做一些奇怪的事情(请阅读问题的“编辑最终-复制问题:”了解更多详细信息)。 问题是文件未保存,因为在写入完成之前,应用程序已关闭。解决办法其实很简单。对于我的Save方法,这是一项任务,它只应在写入完成时返回真值,并且在关闭应用程序时应检查该值

bool saved = await saveDataAsync<T>(whichData, dataFileName)
     if(saved)
         Application.Current.Exit();
bool saved=wait saveDataAsync(whichData,dataFileName)
如果(已保存)
Application.Current.Exit();
序列化方法如下所示(我使用semaphoreSlim,以防两个方法试图访问同一个文件)

public async任务saveDataAsync(T whichData,string dataFileName)
{
var Serializer=新的DataContractSerializer(typeof(T));
等待mySemaphoreSlim.WaitAsync();
尝试
{
使用(var stream=wait ApplicationData.Current.LocalFolder.OpenStreamForWriteAsync(dataFileName,CreationCollisionOption.ReplaceExisting))
{
Serializer.WriteObject(流,whichData);
}
}
最后
{
mySemaphoreSlim.Release();
}
返回true;
}

您是否也在某处序列化文件?这似乎是一个线程问题——写后读的危险。文件操作-读/写都应该在关键部分(只允许一个线程)。在C#中,这意味着读和写都应该由锁(_mySyncRoot){}保护,_mySyncRoot应该是读和写的相同对象。谢谢您的回复。我没有想出这个来寻找解决方案,听起来就是这样。我将在今天晚些时候实现它,经过几周的测试后,如果它确实有效,我将发布它。
bool saved = await saveDataAsync<T>(whichData, dataFileName)
     if(saved)
         Application.Current.Exit();
    public async Task<bool> saveDataAsync<T>(T whichData, string dataFileName)
    {
        var Serializer = new DataContractSerializer(typeof(T));
        await mySemaphoreSlim.WaitAsync();
        try
        {
            using (var stream = await ApplicationData.Current.LocalFolder.OpenStreamForWriteAsync(dataFileName, CreationCollisionOption.ReplaceExisting))
            {
                Serializer.WriteObject(stream, whichData);
            }
        }
        finally
        {
            mySemaphoreSlim.Release();
        }
        return true;
    }