.NET - Why is disposing of standard output only allowed during unit tests?

你说的曾经没有我的故事 提交于 2019-12-23 02:36:27

问题


First of all, I want to point out that I do not really want to dispose of the standard output...I just want to know why I'm seeing the described behavior. I didn't write the bad code described.

I'm using .NET 4 for the unit tests and .NET 3.5 for the code being tested. I'm using MSTest for .NET 4 as my testing framework.

Recently I have been working with a library that was throwing errors due to the blunder of disposing of the standard error output. (See LibTiff.NET ReadDirectory is giving System.ObjectDisposedException Only During Unit Tests).

This is relatively what their code looked like:

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

Basically, when not running unit tests, the standard output is not disposed even if one specifically disposes of it, but when running unit tests, it is allowed.

Can anyone explain why the standard output is disposable only when doing so in the context of unit tests?


回答1:


Calling a method on a disposed object will throw ObjectDisposedException. E.g.:

var textWriter = Console.Error;
textWriter.Dispose();
textWriter.WriteLine("Test");

The last line should throw an exception. Except it doesn't always to that.

If you peruse the BCL source code you can see that Console either uses a StreamWriter (really a synchronized stream writer) that is hooked up to either a "real" stream (e.g. the console error stream) or if that is not available to StreamWriter.Null.

The "real" StreamWriter is constructed in a special way so that it is not closeable. This means that even if you close it (or dispose it) it just continues to function as expected.

So if you have a "real" console stream you can close Console.Error as many times as you want without closing the underlying stream. Also you wont get any ObjectDisposedException.

If there is no "real" stream attached to Console.Error closing the StreamWriter will close the underlying stream (in this case Stream.Null) which doesn't exhibit the special non-closeable behavior, and if you try to use the StreamWriter later you will get an ObjectDisposedException.

The bottom line is that you can get a ObjectDisposedException if you close a console stream writer prematurely in an application that doesn't have a real console stream.

The information above also applies to Console.Out.




回答2:


The problem is likely due to the fact that MSTest uses the standard output stream. In addition to writing timings into the stream, when you run tests, the standard output is actually stored and available in the test results. By disposing of the standard output stream, you're likely interfering with the testing framework's operation itself.

That being said, this is a bug - so your test is showing you something you shouldn't be doing in the first place.... Luckily, the library has corrected this error, so you should be good in the future.



来源:https://stackoverflow.com/questions/12285370/net-why-is-disposing-of-standard-output-only-allowed-during-unit-tests

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