2015-07-29 2 views
6

У меня есть 3 ObservableCollections в моем ViewModel и один Class, который я загружаю при запуске приложения. Для обеспечения десериализации ObservableCollections я только что получил.Обеспечьте десериализацию данных/сериализацию

if(SomeCollection.Count == 0) 
    ThisCollection = await deserializationMethod<ObservableColletion<T>>(filename); 

Если нет файла, deserializationMethod создаст новый объект с

return Activator.CreateInstance<T>(); 

Это прекрасно работает - нет проблем с этим.

А для класса У меня есть

if(ClassObject.Loaded != true) 
    ThisObject = await deserializationMethod<T>(filename); 

Я добавил свойство - если файл десериализации, то это правда. Похоже, что это работает, но это НЕ. Это случается очень редко, но иногда файл не десериализуется, и когда вы используете приложение, этот файл перезаписывается, поэтому все данные уничтожаются. Я не могу найти причину проблемы. Это то, что вы просто запускаете приложение, и это происходит - как раз на 100 запусков.

Как быть уверенным, что если файл существует, то он будет десериализован точно? Или, может быть, я должен сделать List из этих ObservableCollections + Class и сериализовать его в одном файле? Есть ли хорошая практика с этим?

EDIT:

Я использовал SemaphoreSlim, чтобы убедиться, что все используется, как предполагалось, но сегодня это случилось снова.

Дело в том, что приложение запускается, и ничто другое не прослушивается. В данный момент ничего не говорится. Похоже, что данные не десериализованы или не читают существующий файл. Поскольку все изменения записываются с закрытием приложения, все пропадает. Любые другие идеи, какими могут быть или как быть уверенными в десериализации данных?

EDIT FINAL - воспроизведен проблема:

я наконец воспроизведен, что происходит. Поэтому я удалил исправления с кодом, который здесь не нужен.

У меня есть BackPressed событие для обработки, когда пользователь возвращается или хочет выйти из приложения (если на MainPage). Эта часть кода, по-видимому, вызывала проблему. То, что происходит точно. Прежде всего, проблема не может быть воспроизведена с использованием эмулятора. Мой метод BackPressed содержит метод сериализации, который сохранил данные, которые были позже удалены (так, как писал ондрей Свейдар, он писал перед чтением). НО я начал проверять его, и есть странное поведение, и у меня все еще есть некоторые вопросы об этом.

Как это происходит.

Когда я начал приложение (например, случайно) и загрузился экран, я несколько раз нажимаю кнопку «Назад» -> приложение не работает, оно закрывается как можно скорее, и я даже не вижу пользовательский интерфейс (иногда я способный мгновенно увидеть AppBar). Затем, когда я снова пытаюсь открыть приложение (неважно, сразу или позже), он «возобновляется», и после этого момента мои данные исчезли. Но не все данные. Только последний сохранен с ожиданием в пределах метода BackPressed.Только это. Я попытался сохранить один, два и три ObservableCollections с этим классом и без него, и ВСЕГДА последний был сохранен «пустым». После этого я получил метод Application.Current.Exit(), который может вызвать это, но я не уверен, что это должно иметь значение, когда метод сериализации - Задача, и только последняя неверно сериализована.

Когда я удаляю это из метода BackPressed, я не могу воспроизвести эту проблему, так что это она.

Вопросы, которые у меня все еще есть: Ожидается ли такое поведение? Есть ли лучший способ закрыть приложение и обеспечить сериализацию данных, или я просто должен сохранить его во время использования приложения, не выходя из него?

+2

Вы сериализации файл где-нибудь, а? Это похоже на проблему с резьбой - читайте после опасности записи. Работа с файлом - чтение и запись должны находиться в критическом разделе (разрешен только один поток). В C# это означает, что и чтение, и запись должны быть защищены блокировкой (_mySyncRoot) {}, а _mySyncRoot должен быть тем же самым объектом для чтения и записи. –

+0

Благодарим вас за ответ. Я не придумал, что ищет решение, и это звучит так. Я буду реализовывать это позже сегодня, и после нескольких недель тестирования я опубликую, если это сработает. –

ответ

0

Если кому-то интересно, как это сделать должным образом, я подумал об этом и придумал несколько выводов. Имейте в виду, что это мои предложения, и там может быть лучший подход.

При обработке BackPressedButton событие (аппаратное один) у меня была реализация GoBack на предыдущую страницу (если не на MainPage) или оставить приложение, если на MainPage. Я закрывал приложение, используя Application.Current.Exit(), и это не вызывало проблем (потому что я сохранял очень маленькие файлы), пока не начал делать странные вещи (см. «EDIT FINAL - воспроизведенная проблема:« вопроса для более подробной информации). Thing был файл не был сохранен, потому что приложение было закрыто, прежде чем запись закончилась. Решение на самом деле очень простое. К моему Сохранить метод, который является Задача он должен просто вернуть значение true значение, когда запись закончена, и это значение необходимо проверить при закрытии приложения.

bool saved = await saveDataAsync<T>(whichData, dataFileName) 
    if(saved) 
     Application.Current.Exit(); 

и метод сериализации выглядит следующим образом (я использую semaphoreSlim в случае, если есть возможность двумя способами пытаются достичь того же файла)

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; 
    } 
Смежные вопросы