3009Robin
3009Robin

Reputation: 21

Reading/Writing Async Files for Universal App

im trying to Reading/Writing Async Files for an Universal App in c#. When i write and read a file for first time, it works... But when i retry it immeadiatly, there are two Errors: 1. UnauthorizedAccess 2. Handle with the OPLOCK has been closed

It seems that the methods arent finished yet and so the data is not free

(in my frame is a button which adds a new member to a List, then the list shall serialized in an XML data. When i reNavigate to that page, that XML sheet shall be deserialized back to that List, because the Content shall be displayed)

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();
        }
    }

So what can i do and why is it so difficult??(normal I/O is easy-peasy).-.

Upvotes: 2

Views: 599

Answers (3)

Stephen Cleary
Stephen Cleary

Reputation: 457017

As I describe in my MSDN article on async best practices, you should avoid async void:

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

Once your methods are properly async Task, then you can await them:

await WriteImmoListAsync();   
await ReadImmoListAsync();

await WriteImmoListAsync();
await ReadImmoListAsync();   

Upvotes: 2

PhilDulac
PhilDulac

Reputation: 1325

It might be that the process writing/reading the file are still attached to the file. You might want to take a look at this pattern for async file read/write from Microsoft:

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

Also, note that if the read and write are done from differents process, you're going to have to use a mutex. Here's a great explanation on how it works:

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

Upvotes: 0

Jeremy Kato
Jeremy Kato

Reputation: 467

You can't start the methods again until you wait for them to complete. What that above code is trying to do is to write to a file, but while that's processing, it tries to open the file and write to it while the first method call hasn't completed. You need to wait for those method calls to finish before running them again - using the await keyword would be helpful here

Upvotes: 0

Related Questions