Есть ли класс дочернего текста, который запускает событие, если написан текст?
-
02-10-2019 - |
Вопрос
Я написал метод, который принимает TextWriter
как аргумент (обычно консоль., но не обязательно).
Когда я называю этот метод, некоторую информацию о прогрессе записывается текстогворащику. Однако, поскольку этот метод может работать долго, я хочу обновить свой пользовательский интерфейс с некоторой информацией о статусе.
В настоящее время я использую StringWriter
Но у него нет никаких событий. Итак, в первый раз я получу результат от StringWriter
после завершения метода.
Теперь я ищу класс, который наследует от TextWriter
и стреляет в текстовое событие или что -то в этом роде. Я знаю, что это не должно быть трудно реализовать, но держу пари, что команда CLR уже сделала это для меня, я просто не могу найти подходящий класс.
Решение
Если кто -то заинтересован, это класс, который расширяет 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();
}
}
Другие советы
В BCL такого нет, но, как вы уже заметили, это было бы не сложно реализовать.
Удачи.