【发布时间】:2011-12-22 13:06:26
【问题描述】:
在我的 Silverlight/XNA 应用程序/游戏中,我保存自定义类 Level.cs 并将其加载到独立存储。我使用 SharpSerializer 序列化和反序列化关卡。下面的代码结合了几个关于保存和序列化的教程。代码大部分时间都可以工作,但如果我反复保存和加载一个关卡,通常是 2 或 3 次,我会在 Load() 方法中抛出异常。我一直无法追查此异常的原因。现在我正在通过在发生这种情况时从默认 XML 文件重新启动关卡来处理它。
我的问题:
1.) 你知道是什么导致了我的异常,我该如何解决?
2.) 我发现的异常中是否有任何其他详细信息可以帮助我找出造成这种情况的原因?
3.) 有没有更好的方法来构建这段代码?我发现的大多数示例都使用“使用”语句。这种方法有什么优势可以帮助我吗?
其他细节:
奇怪的是,如果我在不保存的情况下退出应用程序然后再次运行应用程序,它将成功加载它刚刚加载失败的独立存储文件。这让我相信保存文件没有损坏,但我可能不会在每次保存/加载时正确处理一些资源,并且随着这些资源在运行应用程序的实例期间累积,最终会导致此问题。
抛出异常时,总是由Load()方法中的这一行抛出:
LoadStream = LoadStorage.OpenFile(loadName, FileMode.Open);
异常描述是{"Operation not allowed on isolatedStorageFileStream."}。我应该寻找的异常中是否还有其他相关细节?无法读取内部异常。
我的保存方法:
public void Save()
{
IsolatedStorageFile SaveStorage = null;
SaveStorage = IsolatedStorageFile.GetUserStoreForApplication();
IsolatedStorageFileStream SaveStream = null;
string saveLName = "levelSave_" + currentLevel.info.number + ".XML";
if (SaveStorage.FileExists(saveLName))
{
SaveStorage.DeleteFile(saveLName);
}
try
{
SaveStream = SaveStorage.CreateFile(saveLName);
var serializer = new SharpSerializer();
serializer.Serialize(currentLevel, SaveStream);
saveState = SaveState.Successful;
}
catch (Exception ex)
{
saveState = SaveState.Failed;
}
finally
{
if (SaveStream != null)
{
SaveStream.Close();
SaveStream.Dispose();
} if (SaveStorage != null)
{
SaveStorage.Dispose();
}
}
}
我的加载方法:
public Level LoadLevel(int levelNumber)
{
IsolatedStorageFile LoadStorage;
LoadStorage = IsolatedStorageFile.GetUserStoreForApplication();
Level tmpLevel;
string loadName = "levelSave_" + levelNumber + ".XML";
if (LoadStorage.FileExists(loadName))
{
IsolatedStorageFileStream LoadStream = null;
try
{
LoadStream = LoadStorage.OpenFile(loadName, FileMode.Open);
var serializer = new SharpSerializer();
tmpLevel = (Level)serializer.Deserialize(LoadStream);
}
catch (Exception ex)
{
tmpLevel = LoadLevelXML(levelNumber);
// Level failed to load from save,
// restart unsaved level from beginning
}
finally
{
if (LoadStream != null)
{
LoadStream.Close();
LoadStream.Dispose();
}
if (LoadStorage != null)
{
LoadStorage.Dispose();
}
}
}
else
{
tmpLevel = LoadLevelXML(levelNumber);
// Level save file not found,
// restart unsaved level from beginning
}
return tmpLevel;
}
我相信 Save() 方法中可能不需要此代码。我只是添加它以确保覆盖文件不是问题。
if (SaveStorage.FileExists(saveLName))
{
SaveStorage.DeleteFile(saveLName);
}
我也认为这两种方法中的这段代码是不必要的,但我再次添加它以确保浮动的“存储”不是问题。
if (LoadStorage != null)
{
LoadStorage.Dispose();
}
在我添加这些代码段之前引发了异常。
【问题讨论】:
-
什么样的代码/交互调用保存?如果您碰巧按了两次按钮,则可能会发生异常,因此在上一个保存操作仍在进行时尝试保存。
-
保存是通过按下按钮调用的。我刚刚添加了检查以查看 saveState 当前是否正在保存。私人无效SaveQuitButton_Click(对象发件人,RoutedEventArgs e){如果(saveState!= SaveState.Saving){Save(); NavigationService.Navigate(new Uri("/MainPage.xaml", UriKind.Relative));另外,我添加了这一行来将 saveState 设置为在 Save 方法中尝试开始时保存。尝试 { saveState = SaveState.Saving; SaveStream = SaveStorage.CreateFile(saveLName); }
-
好吧,格式化完全失败了。
-
Save和Load方法可能同时执行吗?尝试使用lock语句使其线程安全 -
出于好奇,文件有多大?
IsolatedFileStorage默认只支持少量数据。你还应该使用using-statement,而不是使用try...finally。
标签: c# silverlight windows-phone-7 xna isolatedstorage