简体   繁体   中英

MonoTouch File.ReadAllText throws exception on internal FileStream.Dispose()

The following code seems to occasionally produce this stacktrace. It looks like it is happening within the framework when the dispose method is called on the internal FileStream object? Seems like a bug to me, any ideas?

var previousVersion = long.Parse(File.ReadAllText(Paths.VersionFile));

StackTrace:

 System.IO.IOException: Invalid parameter
      at System.IO.FileStream.Dispose (Boolean disposing) [0x00000] in <filename unknown>:0 
      at System.IO.Stream.Close () [0x00000] in <filename unknown>:0 
      at System.IO.StreamReader.Dispose (Boolean disposing) [0x00000] in <filename unknown>:0 
      at System.IO.TextReader.Dispose () [0x00000] in <filename unknown>:0 
      at System.IO.File.ReadAllText (System.String path) [0x00000] in <filename unknown>:0 
      at CatalystHD.Shared.BaseLoginController.CheckIfFirstRunThisVersion () [0x00000] in <filename unknown>:0 
      at CatalystHD.Shared.BaseLoginController.ViewDidLoad () [0x00000] in <filename unknown>:0 
      at MonoTouch.UIKit.UIViewController.get_View () [0x00000] in <filename unknown>:0 
      at CatalystHD.IPad.RootViewController.AnimateTo (MonoTouch.UIKit.UIViewController aController, UIViewAnimationTransition transition) [0x00000] in <filename unknown>:0 
      at CatalystHD.IPad.RootViewController.Logout (Boolean timeout) [0x00000] in <filename unknown>:0 
      at CatalystHD.IPad.NotebookSelectionController.logoutButton_Clicked (System.Object sender, System.EventArgs e) [0x00000] in <filename unknown>:0 
      at MonoTouch.UIKit.UIBarButtonItem Callback.Call (MonoTouch.Foundation.NSObject sender) [0x00000] in <filename unknown>:0 
      at MonoTouch.UIKit.UIApplication.Main (System.String[] args, System.String principalClassName, System.String delegateClassName) [0x00000] in <filename unknown>:0 
      at MonoTouch.UIKit.UIApplication.Main (System.String[] args) [0x00000] in <filename unknown>:0 
      at CatalystHD.Application.Main (System.String[] args) [0x00000] in <filename unknown>:0 

EDIT VersionFile path is grabbed this way:

public static string VersionFile {
    get {
        var path = Environment.GetFolderPath(Environment.SpecialFolder.Personal);
        return Path.Combine(path, "version.dat");
    }
}

If I had to guess, I think you might be running into a race condition due to the implicit Flush() that occurs during disposal of the under-the-hood FileStream in that ReadAllText call.

(caveat: not in front of mono sources, so can't confirm exact behavior)

Is it possible that:

  • You are replacing/reopening/etc. the same file path in another thread?
  • Deleting that path immediately after or in another thread?
  • Otherwise losing access to the checked path? (file share unmounting?)

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