WP7 IsolatedStorage Exception: {"Операция не разрешена для IsolatedStorageFileStream."}
В моем приложении / игре Silverlight/XNA я сохраняю и загружаю собственный класс Level.cs в изолированное хранилище. Я сериализую и десериализую уровень, используя SharpSerializer. Код ниже объединен из нескольких руководств по сохранению и сериализации. Код работает большую часть времени, но если я сохраняю и загружаю уровень повторно, обычно 2 или 3 раза, я получу исключение в методе Load(). Мне не удалось отследить причину этого исключения. Прямо сейчас я обрабатываю это, перезапуская уровень из файла XML по умолчанию, когда это происходит.
Мои вопросы:
1.) Знаете ли вы, что является причиной моего исключения, и как я могу это исправить?
2.) Есть ли какие-либо дополнительные детали в Исключении, которые я улавливаю, которые могут помочь мне выяснить, что является причиной этого?
3.) Есть ли лучший метод для структурирования этого кода? Большинство примеров, которые я нашел, используют операторы "using". Есть ли преимущество этого метода, которое может помочь мне здесь?
Дополнительные детали:
Странно то, что если я выйду из приложения без сохранения, а затем снова запущу приложение, оно успешно загрузит файл изолированного хранилища, который ему не удалось загрузить. Это наводит меня на мысль, что файл сохранения не поврежден, но, вероятно, я не распределяю некоторые ресурсы должным образом каждый раз, когда сохраняю / загружаю, и, поскольку эти ресурсы накапливаются во время запуска приложения, это в конечном итоге вызывает эту проблему.
Когда генерируется исключение, оно всегда генерируется этой строкой в методе Load():
LoadStream = LoadStorage.OpenFile(loadName, FileMode.Open);
Описание исключения: {"Операция не разрешена для 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();
}
Исключение было сгенерировано до того, как я добавил один из этих сегментов кода.
3 ответа
Вы должны использовать концепцию Mutex.
http://msdn.microsoft.com/en-us/library/ff402541(v=vs.92).aspx http://forums.create.msdn.com/forums/p/94965/568077.aspx
У меня есть ощущение, что блокировка операций ввода-вывода может привести к IllegalOperationException
если выполняется в потоке пользовательского интерфейса.
Вы пытались выполнить сериализацию в фоновом потоке (например, используя BackgroundWorker
)?
Теперь, просто ради удовольствия, сделайте это:
lock (SaveStorage)
{
if (SaveStorage.FileExists(saveLName))
{
SaveStorage.DeleteFile(saveLName);
}
}