Pregunta

He escrito un método que acepta un TextWriter como un argumento (Por lo general Console.Out, pero no necesariamente).

Cuando llamo a este método, el progreso algo de información se escribe en el TextWriter. Sin embargo, ya que este método puede funcionar mucho tiempo, quiero actualizar mi interfaz de usuario con un poco de información de estado.

Actualmente, estoy usando un StringWriter pero no tiene ningún evento. Así que la primera vez que llego a consecuencia de la StringWriter es después del método completó.

Ahora estoy buscando una clase que hereda de TextWriter y dispara un evento TextChanged o algo por el estilo. Sé que esto no debería ser difícil de implementar, pero apuesto a que el equipo de CLR ya lo hizo por mí, que no puedo encontrar la clase adecuada.

¿Fue útil?

Solución

Si alguien está interesado, esto es una clase que amplíe la clase StringWriter() a eventos de fuego después de cada llamada a writer.Flush().

También añadió la Varias posibilidades a Flush() llamada automáticamente después de cada escritura, ya que, en mi caso, un componente de terceros, que hizo escribir a la consola, no hizo un color.

Ejemplo de uso:

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);
    }
}

Ahora puede mostrar cierta información de estado justo a tiempo y no es necesario esperar a que el método a fin.

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

Y aquí es la clase:

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();
    }
}

Otros consejos

No hay tal cosa en el BCL, pero como ya se ha notado, esto no sería difícil de implementar.

Buena suerte.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top