2016-06-02 2 views
2

im пытается читать/писать асинхронные файлы для универсального приложения в C#. Когда я пишу и читаю файл в первый раз, он работает ... Но когда я повторяю его небрежно, есть два Ошибки: 1. Несанкционированный доступ 2. Ручка с OPLOCK была закрытаЧтение/запись асинхронных файлов для универсального приложения

Кажется, что методы arent завершен еще и поэтому данные не являются бесплатными.

(в моем кадре кнопка, которая добавляет новый элемент в список, тогда список должен быть сериализован в XML-данных. Когда я перейду на эту страницу, этот лист XML должны быть десериализован обратно в этот список, потому что содержание должно отображаться)

List<Immobilie> immoListe = new List<Immobilie>(); 
private const string FileName_ImmoObjects = "ImmoObjects.xml"; 
StorageFolder sFolder = Windows.Storage.ApplicationData.Current.LocalFolder; 
IStorageFile latestImmoListFile; 

public Startmenue() 
    { 
     this.InitializeComponent(); 
     immoListe.Add(new Immobilie()); // for testing creating an XML first 
     immoListe[0].adresse = "Foo1"; 
     immoListe.Add(new Immobilie()); 
     immoListe[1].adresse = "Foo2"; 
     WriteImmoListAsync(); 
     ReadImmoListAsync(); // These two steps working 

     WriteImmoListAsync(); // everything more causes error 
     ReadImmoListAsync(); 

    } 

public async void WriteImmoListAsync() 
    { 
     try 
     { 
      IStorageFolder folder = await sFolder.CreateFolderAsync("Saves", CreationCollisionOption.OpenIfExists); 
      latestImmoListFile = await folder.CreateFileAsync(FileName_ImmoObjects, CreationCollisionOption.ReplaceExisting); 

      using (IRandomAccessStream stream = await latestImmoListFile.OpenAsync(FileAccessMode.ReadWrite)) 
      using (Stream outputStream = stream.AsStreamForWrite()) 
      { 
       DataContractSerializer serializer = new DataContractSerializer(typeof(List<Immobilie>)); 
       serializer.WriteObject(outputStream, immoListe); 
      } 

     } 
     catch (Exception e) 
     { 
      var d = new MessageDialog(e.ToString()); 
      await d.ShowAsync(); 
     } 
    } 



    public async void ReadImmoListAsync() 
    { 
     int i = 0; 
     try 
     { 
      IStorageFolder folder = await sFolder.GetFolderAsync("Saves"); 
      i = 1; 
      latestImmoListFile = await folder.GetFileAsync(FileName_ImmoObjects); 
      i = 2; 
      using (IRandomAccessStream stream = await latestImmoListFile.OpenAsync(FileAccessMode.Read)) 
      { 
       i = 3; 
       using (Stream inputStream = stream.AsStreamForRead()) 
       { 
        i = 4; 
        DataContractSerializer deserializer = new DataContractSerializer(typeof(List<Immobilie>)); 
        i = 5; 
        immoListe = (List<Immobilie>)deserializer.ReadObject(inputStream); 
       } 
      } 

     } 
     catch (Exception e) 
     { 
      var d = new MessageDialog("Fehler I = " + i + "\n" + e.ToString()); 
      await d.ShowAsync(); 
     } 
    } 

Так что я могу сделать и ж Это так сложно? (нормальный ввод-вывод - легкий-peasy) .-.

ответ

0

Вы не можете запускать методы снова, пока не дождитесь их завершения. То, что этот код пытается сделать, - это записать в файл, но пока он обрабатывается, он пытается открыть файл и записать его, пока первый вызов метода не завершился. Вам нужно дождаться завершения этих вызовов методов, прежде чем запускать их снова - с помощью ключевого слова await было бы полезно здесь

0

Возможно, процесс записи/чтения файла по-прежнему привязан к файлу. Вы можете захотеть взглянуть на этот шаблоне для асинхронного файла для чтения/записи от Microsoft:

https://msdn.microsoft.com/en-ca/library/mt674879.aspx

Кроме того, заметит, что если чтение и запись сделаны из процесса Дифференца, вы будете иметь, чтобы используйте мьютекс. Вот большое объяснение о том, как это работает:

What is a good pattern for using a Global Mutex in C#?

2

Как я описал в своей статье MSDN по async передовой практики, you should avoid async void:

public async Task WriteImmoListAsync(); 
public async Task ReadImmoListAsync(); 

Как только ваши методы должным образом async Task, то вы можете await их:

await WriteImmoListAsync(); 
await ReadImmoListAsync(); 

await WriteImmoListAsync(); 
await ReadImmoListAsync(); 
+0

Спасибо большое Стивен. Чтобы заставить их ждать, я должен был поместить их в новый метод async void. Или есть способ вызвать их из конструктора? – 3009Robin

+0

@ 3009Robin: Я не рекомендую «async void». «Асинхронные конструкторы» сложны; они свидетельствуют о том, что объектная модель не совсем правильная. У меня есть [сообщение в блоге по этому вопросу] (http://blog.stephencleary.com/2013/01/async-oop-2-constructors.html). –

Смежные вопросы