WP7 IsolatedStorage Exception: {"Операция не разрешена для IsolatedStorageFileStream."} - PullRequest
0 голосов
/ 22 декабря 2011

В моем приложении / игре 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 ]

0 голосов
/ 22 декабря 2011

Теперь, просто ради ударов, сделайте это:

lock (SaveStorage)
{
    if (SaveStorage.FileExists(saveLName))
    {
        SaveStorage.DeleteFile(saveLName);
    }
}
0 голосов
/ 23 декабря 2011

Вы должны использовать концепцию Mutex .. ссылаться на эти ..

http://msdn.microsoft.com/en-us/library/ff402541(v=vs.92).aspx http://forums.create.msdn.com/forums/p/94965/568077.aspx

0 голосов
/ 22 декабря 2011

У меня такое ощущение, что блокировка операций ввода-вывода может вызвать IllegalOperationException, если выполняется в потоке пользовательского интерфейса.

Вы пытались выполнить сериализацию в фоновом потоке (например, используя BackgroundWorker)?

...