Y at-il une classe enfant TextWriter qui déclenche l'événement si le texte est écrit?
-
02-10-2019 - |
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.
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.