简体   繁体   中英

StorageFile access denied exception in windows 8

I have a metro style app that polls a file (which is a reference to a StorageFile object) stored in isolated storage every X seconds.

Its a PDF file, and in my app I am allowing the user to open the document and make changes to the document using the native Reader app.

My issue is that I call OpenStreamForReadAsync on the StorageFile when I am polling the document, but if you do this at a precise moment when the user is saving changes made to the document in the Reader app, I get an Access denied exception being thrown.

I am assuming that its is because Windows is writing to the file, which is fine, I just need to know how I can query the local StorageFile reference to see if I am allowed to open it. (ideally without calling OpenStreamForReadAsync wrapped in a try catch).

The Windows team would tell you to do the try/catch thing. That's what they told me when I asked for a File.Exists() API.

The reasoning is this: Suppose the API you are looking for existed... what happens if, during the milliseconds between when you call that API and when you try to open the file, the file is opened/deleted/renamed? BOOM! You're back to the original exception and needing to do a try/catch in order to avoid hard-to-reproduce crashes. So since you need to catch this exception anyways, you might as well just catch the exception. By not providing File.Exists or the API you're looking for, they force us to catch the exception so users won't hit these rare race-condition bugs.

If you prefer not to use a Try Catch block then you'll have to manually keep track of which files you are updating at any given time. Before your async call to save the file, add a unique ID for the file like its path or a hashed value of its path to a List collection. Then immediately following the await save call, remove it from that list.

Any time you go to poll your PDF, check if its UID is in your List. If it is in the list, defer the check. Keep deferring the check until it is no longer in that list.

OR You can also simply create a module level blnSaving boolean variable. Before saving, set it to true. When done saving, set it to false. When polling the PDF, defer the check if the that value is set to true.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM