locked
Maintaining open files and broken oplocks

    Question

  • Hi all,

    I have developed and am currently maintaining a PDF reader/editor app. We're having some problems with the file IO, using StorageFiles and streams. This post might be somewhat long winded, so bear with me.

    We are using a Bug Reporting package to give us crash data. The most common crash has the following stacktrace:

    0System.Exception: The handle with which this oplock was associated has been closed. The oplock is now broken.
    1
    2The handle with which this oplock was associated has been closed. The oplock is now broken.

    We've only ever seen it once in-house, over many hours of developing and testing, and it happened when the app was

    just switched out, which might mean that the app was about to suspend or something.

    I've also managed to break the oplock by switching away from the app, then open the same file in another program, then modifying and saving it in the other program. When my program comes back into view the oplock is broken. I added a check for this and made the app re-open the file if the oplock was broken in this instance.

    The way we are using the StorageFile is as follows.

    The user selects a StorageFile with the file picker. We then create a PDF document class, which maintains a reference to the StorageFile under the hood. We then open the stream for reading using StorageFile::OpenAsync(FileAccessMode::Read).

    In order to optimize performance, the stream is never closed again until the PDF document is disposed.

    Also, different threads might be reading simultaneously. When this happens, we clone the stream and the other thread reads using the exact same method.

    We have an auto-save function, which will try to save the document every 30 seconds if it is modified. In that case, we open a read-write stream (StorageFile::OpenAsync(FileAccessMode::Read)). We close all the read streams, save, and then re-open (at least, this is the intention. If this isn't done correctly, could this cause a problem?).

    At the end, I was wondering if there was anyone here with more experience with these things, as we sort of feel like we're fumbling in the dark. Using StorageFiles, what can cause this to happen? What does Windows 8 do to an app when it's suspended in terms of open files? Could it be a timing issue? Could/Should I close the document while the app is suspended and then re-load the state when it is resumed?

    Also, I found this: http://stackoverflow.com/questions/13792518/exception-when-reading-text-from-the-file-using-fileio-readtextasync

    But I haven't been able to reproduce this issue in a sample app even when trying really hard to read and write from/to a file with multiple threads.

    I realize this is quite open-ended, but I would appreciate any suggestions.

    Thanks,

    Tomas

    Tuesday, June 24, 2014 8:19 PM

All replies

  • We had the same issue with an app here at MS and the root cause was investigated. In a nutshell, the OPLOCks do not close automatically when an app is suspended. You should ensure that all open file handles are closed on app suspend.  They should break when the app terminates.

    I don't know if this is your entire issue, but hopefully this will prevent some of the problems.

    Matt Small - Microsoft Escalation Engineer - Forum Moderator
    If my reply answers your question, please mark this post as answered.

    NOTE: If I ask for code, please provide something that I can drop directly into a project and run (including XAML), or an actual application project. I'm trying to help a lot of people, so I don't have time to figure out weird snippets with undefined objects and unknown namespaces.

    Wednesday, June 25, 2014 12:29 PM
    Moderator
  • Thanks for the feedback Matt.

    It sounds plausible that this somehow is the cause.

    I'd just like to confirm a few things before I dive into a fairly substantial addition to our app to implement this.

    What you're saying sounds like it should be a problem if another app wants access to the same file. But it doesn't exactly explain why our app is crashing. The main question I have is: does the OS sometimes rip away the oplock from under our feet while in a suspended state?

    Best Regards,

    Tomas Hofmann


    Thursday, July 3, 2014 7:04 PM
  • I don't think that it matters about cuoncurrent access at all. It seems more likely that a file handle is opened, the oplock is on the file, and then the app goes into suspend mode.  The file handle closes but the oplock still exists, and then it throws this exception at that time.  That's why you need to explicitly close the files during suspend.

    Matt Small - Microsoft Escalation Engineer - Forum Moderator
    If my reply answers your question, please mark this post as answered.

    NOTE: If I ask for code, please provide something that I can drop directly into a project and run (including XAML), or an actual application project. I'm trying to help a lot of people, so I don't have time to figure out weird snippets with undefined objects and unknown namespaces.

    Thursday, July 3, 2014 7:19 PM
    Moderator