Question

J'ai écrit une méthode qui accepte un TextWriter comme argument (En général Console.Out, mais pas nécessairement).

Quand j'appelle cette méthode, quelques informations de progression est écrit dans le TextWriter. Cependant, étant donné que cette méthode peut fonctionner longtemps, je veux mettre à jour mon interface utilisateur avec des informations d'état.

À l'heure actuelle, je me sers d'un StringWriter mais il n'a pas de événements. La première fois que je reçois un résultat de la StringWriter est après la méthode terminée.

Maintenant, je suis à la recherche d'une classe héritant de TextWriter et déclenche un événement TextChanged ou quelque chose comme ça. Je sais que cela ne devrait pas être difficile à mettre en œuvre pour, mais je parie que l'équipe CLR déjà fait pour moi, je ne peux pas trouver la classe appropriée.

Était-ce utile?

La solution

Si quelqu'un est intéressé, il est une classe qui étend la classe StringWriter() aux événements d'incendie après chaque appel à writer.Flush().

J'ai aussi ajouté le posibillity à Flush() appel automatiquement après chaque écriture, puisque, dans mon cas, un composant tiers, qui a fait écrire à la console, n'a pas fait une chasse d'eau.

Exemple d'utilisation:

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

Maintenant je peux afficher des informations d'état juste à temps et ne pas besoin d'attendre la méthode à la fin.

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

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

Autres conseils

Il n'y a pas une telle chose dans la BCL, mais comme vous l'avez déjà remarqué, ce ne serait pas difficile à mettre en œuvre.

Bonne chance.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top