装饰System.Console.Out添加颜色

时间:2013-01-01 18:29:10

标签: .net f# console-application

我有简单的功能

let OutputDebugToConsole () =
    new System.Diagnostics.TextWriterTraceListener(System.Console.Out)
        |> System.Diagnostics.Debug.Listeners.Add |> ignore

将调试输出从Debug.WriteLine重定向到控制台。

例如,我希望通过将Console.ForegroundColor设置为灰色来使调试输出具有不同的颜色。显然,每次写入后都需要重置颜色,以便以标准颜色书写普通文本。我的想法是传递一个不同的TextWriter来装饰Write方法。

首先,这是一种思考问题的合理方式吗?第二,要做到这一点,我需要重写我TextWriter的所有方法,还是有不同的方法?

2 个答案:

答案 0 :(得分:5)

Console.ForegroundColor同时具有属性getter和setter,因此技术上可以简单地存储旧颜色,分配,写入和恢复旧颜色。

但这样做并不是线程安全的。另一个线程也可以使用Console.Write并指定ForegroundColor属性以获取其自己的首选颜色。这是一场比赛,你的记录器最终可能会用另一个线程选择的颜色进行书写。反过来说。有一个锁可以阻止两个线程将文本写入控制台并使其输出混合,但是这样做太迟了。除了让你的记录器使用pinvoke以便它根本不需要使用ForegroundColor之外,没有简单的方法可以解决这个问题。

如果有的话,这是一个非常简单的细节。这就是为什么通常最好使用一个记录库来处理这些讨厌的小细节。例如NLog。

答案 1 :(得分:3)

您可以使用Printf.kprintf函数以相当简单的方式实现此功能,如本博文中所示:Colored printf

基本上,Printf.kprintf接受格式化字​​符串应用的延续;我链接的博客文章显示了如何传递一个延续,它设置控制台颜色,打印字符串,然后在返回之前恢复原始颜色。

正如Hans Passant在他的回答中写道,设置/恢复控制台颜色存在线程安全问题,因此您应该确保相应地设计应用程序(如果您使用多个线程或F#async工作流程)。