Можно ли настроить трассировку через TraceSource через код из внешней сборки

Наиболее TraceSource Примеры трассировки показывают, как это делается с помощью конфигурации. Я пытаюсь добиться этого с помощью кода.

У меня есть простая сборка следующим образом:

using System;
using System.Diagnostics;
using System.Threading;

namespace TracingLib
{
    public class AppTracer
    {
        public event EventHandler AppStarted;
        public event EventHandler AppStopped;
        private bool CancelRequested = false;
        public void Start()
        {
            Thread thread = new Thread(new ThreadStart(() =>
            {
                if(AppStarted != null) AppStarted(this, new EventArgs());

                TraceSource ts = new TraceSource("ThreadSource");

                ts.TraceInformation("Thread Begins");
                //ts.Flush();
                int i = 0;
                while (!CancelRequested)
                {

                    ts.TraceInformation("i: {0}", i++);
                    //ts.Flush();
                    Debug.Print("i : {0}", i);
                    Thread.Sleep(5000);
                }

                if (AppStopped != null) AppStopped(this, new EventArgs());
            }));
            thread.Start();
        }

        public void Stop()
        {
            CancelRequested = true;
        }
    }
}

Я потребляю это в консольном приложении.

using System;
using System.Threading;
using TracingLib;

namespace caTracingLibImplementation
{
    class Program
    {
        static void Main(string[] args)
        {
            AppTracer tracer = new AppTracer();
            ManualResetEvent waiter = new ManualResetEvent(false);
            tracer.AppStopped += (sender, e) =>
            {
                waiter.Set();
            };

            TraceSource ts = new TraceSource("ThreadSource");            
            ts.Listeners.Add(new ConsoleTraceListener());
            var sw = new SourceSwitch("foo");
            sw.Level = SourceLevels.Warning;
            ts.Switch = sw;
            tracer.Start();
            Console.WriteLine("AppTracer started...");
            Thread.Sleep(10000);
            tracer.Stop();
            Console.WriteLine("AppTracer stopped...");
            Console.WriteLine("Waiting to stop...");
            waiter.WaitOne();
            Console.WriteLine("End of program");
        }
    }
}

Если я пытаюсь включить трассировку через консольное приложение, я не вижу сообщений трассировки.

2 ответа

Во-первых, вам необходимо предоставить TraceListeners для TraceSource, определенного в AppTracer.

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

Если строковый параметр для TraceSource не определен в app.config, то слушатели не будут сохранены в глобальном состоянии. Поэтому каждый экземпляр TraceSource должен иметь всех слушателей, предоставленных ему.

Источник TraceSource.Initialize()

Во-вторых, переключатель: sw.Level = SourceLevels.Warning; отключит любые операторы, зарегистрированные с: ts.TraceInformation()

Если вы настраиваете свой TraceSource во время выполнения, я думаю, что наиболее подходящим решением для вашего кода является:

  1. Добавьте этот динамический TraceSource в конструктор AppTracer.
  2. ИЛИ передать TraceSource через Start().

Я бы склонился к #1 над #2.

Как упоминает пользователь1112560, вы не увидите вывод TraceInformation, если для вашего уровня переключателя установлено предупреждение. Приоритет: Выкл., Ошибка, Предупреждение, Информация, Подробно. Посмотрите Коммутаторы трассировки MSDN.

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