Domanda

Ho scritto un metodo che accetta un TextWriter come argomento (Generalmente Console.Out, ma non necessariamente).

Quando chiamo questo metodo, alcune informazioni di avanzamento viene scritto nel TextWriter. Tuttavia, dal momento che questo metodo può funzionare a lungo, voglio aggiornare il mio UI con alcune informazioni di stato.

Al momento, sto usando un StringWriter ma non ci sono eventi. Così la prima volta che ricevo un risultato dalla StringWriter è dopo il metodo completato.

Ora sono alla ricerca di una classe che eredita da TextWriter e genera un evento TextChanged o qualcosa di simile. So che questo non dovrebbe essere troppo difficile da realizzare, ma scommetto che la squadra CLR già fatto per me, non riesco proprio a trovare la classe appropriata.

È stato utile?

Soluzione

Se qualcuno è interessato, questa è una classe che estende la classe StringWriter() agli eventi del fuoco dopo ogni chiamata a writer.Flush().

Ho anche aggiunto la si accettano per Flush() chiamata automaticamente dopo ogni scrittura, dal momento che, nel mio caso, un componente di terze parti, che ha scritto alla console, non ha fatto un colore.

Utilizzo di esempio:

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

Ora è possibile visualizzare alcune informazioni sullo stato appena in tempo e non c'è bisogno di aspettare per il metodo alla fine.

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

E qui è la classe:

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

Altri suggerimenti

Non v'è nulla di simile nel BCL, ma come hai già notato, questo non sarebbe difficile da attuare.

In bocca al lupo.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top