# 原理
Console 有一个方法叫做 SetOut ,支持一个 TextWriter 的参数,调用之后,控制台的所有输出将不会经过标准输出流,而是经过自定义的流。
可以重定向本程序的控制台输出至文本流或其他部分。我写这个主要为了将 Blazor 的控制台输出显示到界面上,但是有个问题,无法获取文本颜色,现在也没什么解决方案。
# 实现
# 创建一个继承自 TextWriter 的类
- 继承
TextWriter - 重写
Write(char) 、 Write(string) 以及 WriteLine 方法,这样能够覆盖八成以上的场景,父类有更多的输出方法,按需重写
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| private class ObservableTextWriter : TextWriter { public override Encoding Encoding => Encoding.Default;
public override void Write(char value) { }
public override void Write(string value) { }
public override void WriteLine(string value) { } }
|
# 暴露写入事件
外部监听事件即可获取控制台输出内容
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| private class ObservableTextWriter : TextWriter { public override Encoding Encoding => Encoding.Default;
public event Action<string> OnWrite;
public override void Write(char value) { OnWrite?.Invoke(value.ToString()); }
public override void Write(string value) { OnWrite?.Invoke(value); }
public override void WriteLine(string value) { OnWrite?.Invoke(value); } }
|
# 防抖
如果只是调用 Write(string) 或 WriteLine 还好,我发现 Blazor 会调用很多 Write(char) ,导致每次控制台有输出时,都会卡死 UI,所以我使用防抖来降低向 UI 通知的速度。
防抖器的实现请参考另一篇文章
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40
| private class ObservableTextWriter : TextWriter { public override Encoding Encoding => Encoding.Default;
public event Action<string> OnWrite;
private Debouncer Debouncer { get; set; } = new();
private StringBuilder StringBuilder { get; set; } = new();
public override void Write(char value) { StringBuilder.Append(value); Debouncer.Debounce(() => { OnWrite?.Invoke(StringBuilder.ToString()); StringBuilder.Clear(); }, 500); }
public override void Write(string value) { StringBuilder.Append(value); Debouncer.Debounce(() => { OnWrite?.Invoke(StringBuilder.ToString()); StringBuilder.Clear(); }, 500); }
public override void WriteLine(string value) { StringBuilder.AppendLine(value); Debouncer.Debounce(() => { OnWrite?.Invoke(StringBuilder.ToString()); StringBuilder.Clear(); }, 500); } }
|