0

Edit: FYI for future readers, this issue has been fixed as of version 2.3.606.0 of BitMiracle's LibTiff.NET.

I'm using BitMiracle's LibTiff.NET (version 2.3.605.0 and below) in my C# library (compiled at .NET 3.5 | x86) and keep getting this exception when I call ReadDirectory: System.ObjectDisposedException: Cannot write to a closed TextWriter

I realize that this seems to indicate that I have already disposed of my image before making the call...but I have not specifically done so. Is this a bug in the library or am I really missing something here?

Here is my code:

    public static bool IsTiffBiTonal(String tiffFilePath)
    {
        VerifyFileExistence(tiffFilePath);

        using (Tiff tiff = Tiff.Open(tiffFilePath, "r"))
        {
            do
            {
                if (tiff.GetField(TiffTag.BITSPERSAMPLE)[0].ToInt() == 1)
                {
                    continue;
                }
                return false;
            }
            while (tiff.ReadDirectory()); //Error occurs here
        }
        return true;
    }

EDIT: Ok, I have more information after some further testing, this is only happening when I'm running my unit tests! Don't know why that would change anything though.

bsara
  • 7,940
  • 3
  • 29
  • 47

1 Answers1

2

Because of other threads talking about unit testing and getting this same error when trying to write to the console (ObjectDisposedException when outputting to console) I realized that the LibTiff.NET library was trying to write to the error console. After looking through the source code, I found that this code:

        using (TextWriter stderr = Console.Error)
        {
            ...
        }

Because they were wrapping all of the writes to the error out in a using, it was disposing of the Console.Error object after the first write to the error out. This caused my error on the second time around (ReadDirectory does what calling Next on a linked list does). So I removed the using and the problem was fixed!

        TextWriter stderr = Console.Error;
        ...

So, the lesson here: don't dispose of your standard outputs :)

I've asked another question regarding why they were ever allowed to dispose of the standard output in unit tests but not in other situations here: .NET - Why is disposing of standard output only allowed during unit tests?. If you have any answers to the question...please post it there.

Community
  • 1
  • 1
bsara
  • 7,940
  • 3
  • 29
  • 47
  • Either your production code doesn't touch that code in normal execution, happens on a background thread, or console isn't allocated in an exe process -- best guesses. – bryanbcook Aug 26 '12 at 01:28
  • @bryanbcook Well, I know that it hits it in normal execution...that's how I found where the problem would probably be. I wonder if for some reason during normal execution, because an actual shell exists, it won't allow for one to dispose of the standard outputs...but with unit tests no such setting or shell exists? – bsara Aug 27 '12 at 16:15
  • 1
    Windows applications do not allocate a Console from the operating system, so likely any attempt to interact with them is ignored. Unit tests however, do have a console so it matters. – bryanbcook Aug 27 '12 at 19:03
  • Having worked extensively with libtiff, I am not surprised that the .NET version does insanely stupid things. – Ed S. Sep 04 '12 at 21:29
  • @EdS. I've found the same with most .NET ports of libraries...however, this is the only issue that I've come up against so far...it's actually a really well built library from what I can tell. One of the best commented libraries that I've found too. – bsara Sep 05 '12 at 15:43
  • @Brandon: Well, to be fair... I was a bit cranky with libtiff when I wrote that :). I was in the middle of tracking down a case of heap corruption in the C library. We use an older version of libtiff as well, and a lot of that has been fixed. I was venting. – Ed S. Sep 05 '12 at 17:28