Запись в файл журнала: использование (... new StreamReader) каждый раз, когда я пишу строку?
Я написал программу автоматизации с кнопкой "Пуск" и "Стоп", которая выполняет различные задачи снова и снова, пока пользователь не нажмет кнопку "Стоп". В программе у меня есть несколько Console.WriteLines, которые показывают результат каждой маленькой подзадачи. Я решил преобразовать их в журнал.txt, чтобы я мог просмотреть после закрытия программы или в случае сбоя.
Я сделал следующий класс Logger:
class Logger
{
private string _logName;
public Logger(string logName)
{
_logName = logName;
using (StreamWriter w = File.AppendText(_logName + ".txt"))
{
w.WriteLine("-------------------------------");
}
}
public void Log(string logMessage)
{
using (StreamWriter w = File.AppendText(_logName + ".txt"))
{
w.WriteLine(DateTime.Now.ToLongDateString() + " " + DateTime.Now.ToLongTimeString() + " " + logMessage);
}
Console.WriteLine(logMessage);
}
}
Вопрос: в другом классе у меня есть экземпляр Logger с именем _logger. Я звоню _logger.Log снова и снова, каждый раз, когда я хочу записать строку в журнал. Иногда это идет очень быстро друг за другом. Кажется неправильным создавать новый экземпляр StreamWriter каждый раз, когда я записываю строку в журнал (в операторе using). Поэтому я подумал о создании экземпляра StreamWriter в конструкторе, но это нарушает функции очистки оператора using, не так ли?
Есть идеи, как лучше всего это сделать?
Заранее спасибо.
2 ответа
Вы можете убедиться, что поток будет удален / закрыт, когда вы закончите (например, когда экземпляр этого класса будет удален):
public sealed class Logger : IDisposable
{
private string _logName;
private StreamWriter _stream;
public Logger(string logName)
{
_logName = logName;
_stream = File.AppendText(_logName + ".txt");
}
public void Log(string logMessage)
{
_stream.WriteLine(DateTime.Now.ToLongDateString() + " " + DateTime.Now.ToLongTimeString() + " " + logMessage);
}
public void Dispose()
{
_stream.Dispose();
}
}
Теперь вы также можете использовать свой регистратор с using
-заявление:
using (Logger log = new Logger("Path"))
{
log.Log("Something");
// do something else...
log.Log("Something else");
}
Или вы можете использовать доступную библиотеку журналов: .NET Framework ведения журналов
Вы можете сделать свой класс логгера одноразовым, теперь вызывающая сторона должна инициировать очистку.
class Logger : IDisposeable
{
private string _logName;
private StreamWriter _w;
public Logger(string logName)
{
_logName = logName;
_w = File.AppendText(_logName + ".txt"))
_w.WriteLine("-------------------------------");
}
public void Log(string logMessage)
{
_w.WriteLine(DateTime.Now.ToLongDateString() + " " + DateTime.Now.ToLongTimeString() + " " + logMessage);
Console.WriteLine(logMessage);
}
public void Dispose()
{
Dispose(true);
}
protected virtual void Dispose(bool disposing)
{
if(disposing)
_w.Dispose();
}
}
Однако, есть гораздо более надежные готовые каркасы логирования, я рекомендую использовать один из них вместо того, чтобы писать свой собственный.