是否有一个TextWriter子类,当文本被写入时会触发事件?

5

我编写了一个方法,它接受一个TextWriter作为参数(通常是Console.Out,但不一定是)。

当我调用这个方法时,一些进度信息会被写入到TextWriter中。 然而,由于这个方法可能运行很长时间,我希望在我的UI上更新一些状态信息。

目前,我正在使用一个StringWriter,但它没有任何事件。所以我第一次从StringWriter获取结果是在该方法完成后。

现在,我正在寻找一个继承自TextWriter并触发TextChanged事件或类似事件的类。 我知道这应该不难实现,但我相信CLR团队已经替我做好了,只是我找不到合适的类。

2个回答

16
如果有人感兴趣,这是一种扩展StringWriter()类的方法,在每次调用writer.Flush()后触发事件。
我还添加了在每次写入后自动调用Flush()的可能性,因为在我的情况下,一个第三方组件向控制台写入时没有执行刷新操作。
示例用法:
void DoIt()
{
    var writer = new StringWriterExt(true); // true = AutoFlush
    writer.Flushed += new StringWriterExt.FlushedEventHandler(writer_Flushed);

    TextWriter stdout = Console.Out;
    try
    {
        Console.SetOut(writer);
        CallLongRunningMethodThatDumpsInfoOnConsole();
    }
    finally
    {
        Console.SetOut(stdout);
    }
}

现在,我可以及时显示一些状态信息,而不需要等待方法完成。

void writer_Flushed(object sender, EventArgs args)
{
    UpdateUi(sender.ToString());
}

以下是该类的代码:

public class StringWriterExt : StringWriter
{
    [EditorBrowsable(EditorBrowsableState.Never)]
    public delegate void FlushedEventHandler(object sender, EventArgs args);
    public event FlushedEventHandler Flushed;
    public virtual bool AutoFlush { get; set; }

    public StringWriterExt()
        : base() { }

    public StringWriterExt(bool autoFlush)
        : base() { this.AutoFlush = autoFlush; }

    protected void OnFlush()
    {
        var eh = Flushed;
        if (eh != null)
            eh(this, EventArgs.Empty);
    }

    public override void Flush()
    {
        base.Flush();
        OnFlush();
    }

    public override void Write(char value)
    {
        base.Write(value);
        if (AutoFlush) Flush();
    }

    public override void Write(string value)
    {
        base.Write(value);
        if (AutoFlush) Flush();
    }

    public override void Write(char[] buffer, int index, int count)
    {
        base.Write(buffer, index, count);
        if (AutoFlush) Flush();
    }
}

在我的情况下,我需要在每次刷新后清除 StringWriter 缓冲区。我在 OnFlush() 方法的末尾添加了 this.GetStringBuilder().Clear();。 - Dave
我的控制台应用程序使用WriteLine()。我直接扩展了TextWriter并发现我不需要覆盖WriteLine()。只有Write()就足够了。 我不确定这是否是一个通用规则,您可以依赖它吗?难道WriteLine()会自动路由到Write()吗? - jifb

2
中没有这样的东西,但正如您已经注意到的那样,这并不难实现。 祝好运。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接