代码之家  ›  专栏  ›  技术社区  ›  Sarah Vessels

输出到控制台时的ObjectDisposedException

  •  1
  • Sarah Vessels  · 技术社区  · 15 年前

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

    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

    你能解释一下为什么会这样吗?我能避免它并得到我想要的更简洁的代码吗?

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

    /// <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 回复  |  直到 15 年前
        1
  •  0
  •   ChaosPandion    15 年前

    唯一的解释是你的测试环境是不同的。例如,在测试一中,您正在编写 StdOut 但是在第二个测试中你写信给 StdErr 因为某种错误。打开调试器,并确保在执行此代码之前不会释放任何一个。

        2
  •  0
  •   Aren    15 年前

    我相信你要找的方法是:

    Console.WriteLine(msg);
    

    Console.Error.WriteLine(msg);
    

    编辑:

    我相信用 Console.Out Console.Error 你可能得用 SetError SetOut 方法。

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

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

    这意味着你可能必须自己写,并设法关闭流,因为这些返回 System.IO.Stream 物体。

    所以:

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

    我只是使用 Console.Write / Console.WriteLine 在我的编码中。阿尔索 Debug.Write Debug.WriteLine 对于错误流。