UnauthorizedAccessException in StorageFile.OpenAsync

删除回忆录丶 提交于 2019-12-01 06:46:05

I had the same issue and had to explicitly dispose the stream and file objects before it would complete.

    var file = await ApplicationData.Current.LocalFolder.CreateFileAsync(filename, Windows.Storage.CreationCollisionOption.ReplaceExisting);
    using (var fs = await file.OpenAsync(Windows.Storage.FileAccessMode.ReadWrite))
    {
        var outStream = fs.GetOutputStreamAt(0);
        var dataWriter = new Windows.Storage.Streams.DataWriter(outStream);
        dataWriter.WriteString("Hello from Test!");
        await dataWriter.StoreAsync();
        dataWriter.DetachStream();
        await outStream.FlushAsync();
        outStream.Dispose(); // 
        fs.Dispose();
    }

You cannot "using" when you use 'await'. The reason is how the compiler transform your C# await/async to IL. You can decompile to see it.

When the processor arrives to:

await writer.StoreAsync();

in reality it returns to the caller immediately (see IL). Since you are using "using", the Dispose interface of `IRandomAccessStream fs is called and the resources are released. These resources are required by the thread initiated in the 'StoreAsync'.

For this reason, you must call Dispose explicitly, after the await.

The same problem appears in try/exception/catch blocks.

It looks to me that you're leaking the stream passed to

    using (DataWriter writer = new DataWriter(fs.GetOutputStreamAt(0)))

If the stream is reference counted (it is winRT after all), then a reference will be held by the temporary object passed to the constructor, and incremented by the constructor in DataWriter.

The temporary object will be awaiting garbage collection.

Does it work if you instead do this:

using (var st0 = fs.GetOutputStreamAt(0))
    using (DataWriter writer = new DataWriter(st0))
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!