Запись в файл журнала: использование (... 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();
    }
}

Однако, есть гораздо более надежные готовые каркасы логирования, я рекомендую использовать один из них вместо того, чтобы писать свой собственный.

Другие вопросы по тегам