C # "кэшированный журнал отладки" - PullRequest
1 голос
/ 03 августа 2011

Я бы хотел попросить совета у экспертов C #.У меня проблема с моим журналом отладки.У меня есть простой класс, который просто открывает файл, записывает предоставленную строку и закрывает файл снова.Однако иногда мне нужно использовать этот журнал отладки, пока я использую многопоточность.Тем самым приходят неприятности.Я не могу открыть файл более одного раза, поэтому получаю исключение, потому что я просто пытаюсь открыть заблокированный файл снова.Для этой цели я хотел бы иметь что-то вроде «кэшированного журнала отладки», который бы предотвращал это исключениеЕсть ли простой способ реализовать это?Заранее большое спасибо.

Ответы [ 3 ]

2 голосов
/ 03 августа 2011

C # 4.0 предоставляет поточно-ориентированные коллекции, такие как System.Collections.Concurrent.ConcurrentQueue<T>. Вы можете изменить свой класс ведения журнала так, чтобы он выполнялся в своем собственном потоке, а вызовы методов ведения журнала просто добавляли сообщение в такую ​​очередь. Таким образом, ваш поток ведения журнала может просто безопасно читать элементы из очереди и записывать в файл без перерыва.

EDIT

Конечно, наиболее целесообразно начать с использования уже существующей среды ведения журналов, которая уже позаботилась об этом. Я бы порекомендовал NLog, хотя log4net также является достойным соперником.

1 голос
/ 03 августа 2011

Возможно, вы захотите проверить .NET Tracing. Я предпочитаю просто использовать встроенные классы TraceSource по сравнению с использованием сторонней среды ведения журналов, такой как nlog. Раньше я шел по пути даже написания фасада вокруг nlog, но тогда кажется довольно глупым иметь так много зависимостей и так много уровней абстракции, просто чтобы написать сообщение журнала.

Обзор TraceSource можно посмотреть здесь: http://msdn.microsoft.com/en-us/library/system.diagnostics.tracesource.aspx

Идея состоит в том, что вы отделяете трассировку от прослушивания. Во всем вашем коде вы можете добавлять вызовы трассировки, каждый из которых имеет разные уровни журнала (Error, Verbose, Debug) и разные источники. В конфигурации вашего приложения вы затем настраиваете различные прослушиватели.

<system.diagnostics>
    <sources>
      <source name="Source1" switchName="verboseSwitch">
        <listeners>
          <add name="console" />
        </listeners>
      </source>
      <source name="Source2" switchName="warningSwitch">
        <listeners>
          <add name="console" />
        </listeners>
      </source>
    </sources>
    <switches>
      <add name="verboseSwitch" value="Verbose" />
      <add name="warningSwitch" value="Information" />
    </switches>
    <sharedListeners>
      <add name="console" type="System.Diagnostics.ConsoleTraceListener" initializeData="false"/>
    </sharedListeners>
    <trace autoflush="true" indentsize="4">
      <listeners>
        <add name="console" />
      </listeners>
    </trace>
  </system.diagnostics>


public void MethodOne()
{
     TraceSource ts = new TraceSource("Source1");

     ts.TraceEvent(TraceEventType.Verbose, 0, "Called MethodOne");

     // do something that causes an error
     ts.TraceEvent(TraceEventType.Error, 0, "MethodOne threw an error");
}

Здесь MethodOne настроен на использование источника «Source1». Source1 в настоящее время настроен выше, чтобы слушать все подробности и выше. Так что это означает, что

Called MethodOne
MethodOne threw an error 

оба будут записаны на консоль

public void MethodTwo()
{
     TraceSource ts = new TraceSource("Source2");

     ts.TraceEvent(TraceEventType.Verbose, 0, "Called MethodTwo");

     // do something that causes a error
     ts.TraceEvent(TraceEventType.Error, 0, "MethodTwo threw an error");
}

Здесь, однако, MethodTwo настроен на использование Source2, который настроен только на прослушивание Warning и выше.

Итак, когда код будет запущен, вывод будет

MethodTwo threw an error

Это позволяет вам контролировать количество информации, которую вы хотите видеть для разных частей вашей программы. Возможно, если однажды вы начнете видеть ошибки в какой-либо библиотеке, вы можете превратить источник трассировки для этой библиотеки в подробный, и теперь увидите всю свою информацию отладки, не перегружаясь данными из других частей программы.

Я использую разных слушателей, подобных этому, чтобы контролировать поток критических ошибок. У меня есть прослушиватели для определенных источников и определенных уровней ошибок, которые отправят мне электронное письмо, как только ошибка будет записана в журнал. Меня не волнует 404 ошибки, но меня волнует все, что происходит в регистрационном коде, например.

У вас есть ConsoleTraceListener для записи в консоль / окно отладки. FileLogTraceListener для записи в файлы Даже EventLogTraceListener

Полный список встроенных слушателей вы можете увидеть здесь

Затем существуют сторонние прослушиватели для отправки сообщений электронной почты о событиях журнала, сохранения в базе данных, записи в хранилище таблиц Azure и т. Д.

Конечно, вы можете выполнить все это с помощью фреймворка, такого как NLog. Методы .NET Trace являются высокопроизводительными и используются во всем .NET Framework. Вы не ошибетесь, выбрав его ИМХО.

1 голос
/ 03 августа 2011

Обычно это делается с помощью одноэлементного логгера, который вы вызываете из всех частей вашего кода; регистратор - единственное, что напрямую обращается к файлу. Уже существует ряд платформ (nlog, log4net, корпоративная библиотека), которые делают это для вас.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...