输出到控制台时出现ObjectDisposedException

时间:2010-05-25 19:08:27

标签: c# exception console dispose

如果我有以下代码,我没有运行时或编译问题:

if (ConsoleAppBase.NORMAL_EXIT_CODE == code)
{
    StdOut.WriteLine(msg);
}
else
{
    StdErr.WriteLine(msg);
}

然而,在尝试使其更简洁时,我切换到以下代码:

(ConsoleAppBase.NORMAL_EXIT_CODE == code
    ? StdOut
    : StdErr
).WriteLine(msg);

当我有这段代码时,我在运行时遇到以下异常:

  

System.ObjectDisposedException:无法写入已关闭的TextWriter

你能解释一下为什么会这样吗?我可以避免使用它并拥有我想要的更简洁的代码吗?

编辑:哎呀,对不起,我忘了记下这些神秘的StdOutStdErr来自哪里:

/// <summary>
/// Define these so that they can be accessible to unit tests so that
/// a different TextWriter instance can be used for capturing output
/// for verification.
/// </summary>
internal static TextWriter StdOut = Console.Out;
internal static TextWriter StdErr = Console.Error;

更新:嗯,我刚才用原始冗长的代码得到了同样的异常,所以显然其他东西都是错误的。我会检查我的测试用例在做什么。

再次更新:在我的测试中结果我正在重新路由标准输出但不是标准错误,但后来我确实尝试写入标准错误并且它已经摆脱了。我的修复:

var standardOut = new StreamWriter(Console.OpenStandardOutput())
                      {
                          AutoFlush = true
                      };
Console.SetOut(standardOut);

// Added this:
var standardError = new StreamWriter(Console.OpenStandardError())
                        {
                            AutoFlush = true
                        };
Console.SetError(standardError);

我将ChaosPandion's answer标记为正确的,因为他正确地将我的测试确定为愚蠢。

2 个答案:

答案 0 :(得分:0)

唯一的解释是您的测试环境不同。例如,在测试1中,您正在编写StdOut,但在测试2中,由于某种错误,您正在写入StdErr。打开调试器,确保在执行此代码之前没有处置它们。

答案 1 :(得分:0)

我相信您正在寻找的方法是:

Console.WriteLine(msg);

Console.Error.WriteLine(msg);

修改

我相信使用Console.OutConsole.Error您可能必须使用SetErrorSetOut方法设置它们。

相反,您可以尝试调用这些函数:

Console.OpenStandardError();
Console.OpenStandardOutput();

这意味着您可能必须创建自己的编写器,并管理关闭流,因为它们会返回System.IO.Stream个对象。

所以:

TextWriter StdOut = new TextWriter(Console.OpenStandardOutput());
TextWriter StdErr = new TextWriter(Console.OpenStandardError());

我只是在编码中使用Console.Write / Console.WriteLine。错误流也是Debug.WriteDebug.WriteLine