Как вызвать dispose на пользовательском слушателе трассировки в C # - PullRequest
2 голосов
/ 06 апреля 2011

Я написал собственный слушатель трассировки, расширяющий TextWriterTraceListener.

Теперь, как мне вызвать Dispose () на слушателе? Я добавляю его через app.config моего проекта.

Попытка добавить вызов Dispose (false) в финализатор, но он не вызывается. Как ни странно, он вызывается в VS 2010, но не когда я запускаю приложение, но я знаю, что сбор GC не гарантирован. (в основном это используется в тестах nunit для регистрации вызовов System.Net.Socket из тестов, и мне нужно выполнить некоторую постобработку после запуска всех тестов и записать это также в журнал. Я добавил эту часть в Dispose ( ))

Фрагмент App.config:

<sources>
  <source name="System.Net.Sockets" tracemode="protocolonly" maxdatasize="10240">
    <listeners>
      <add name="CustomTraceListener" type="Tests.Custom.MyTest.CustomTraceListener, Tests.Custom.MyTest" initializeData="custom.log" />
    </listeners>
  </source>
</sources>

Некоторые фрагменты кода:

    ~CustomTraceListener()
    {
        Dispose(false);
    }

    protected override void Dispose (bool disposing)
    {
        base.Write(customProcessor.PostProcess());
        base.Flush();
        base.Dispose(disposing);
    }

    public void Dispose()
    {
        Dispose(true);
        GC.SuppressFinalize(this);
    }

Ответы [ 3 ]

1 голос
/ 08 апреля 2011

Мне пришлось написать SetUpFixture и в TearDown, использовать некоторое отражение, чтобы получить тип "System.Diagnostics.TraceSource" из сборки, получить закрытое статическое поле, которое представляло собой список всех источников трассировки, и вызвать Dispose () на мой пользовательский слушатель.

FieldInfo[] info = ts.GetType().Assembly.GetType("System.Diagnostics.TraceSource").GetFields(BindingFlags.NonPublic | BindingFlags.Static);

Вызовите Dispose () для всех слушателей TraceSource

foreach (TraceListener listener in s.Listeners)
                {
                   listener.Dispose();
                   Console.WriteLine("disposing");
                }
1 голос
/ 27 мая 2012

Еще один способ сделать это без размышлений:

Вы определяете свой источник трассировки где-то, вероятно, так:

 private static readonly TraceSource trace = 
        new TraceSource("System.Net.Sockets");

Теперь вам все еще нужно Снос или что-то, что вызывается в конце. Вне модульных тестов, вы можете захватить AppDomain.ProcessExit, AppDomain.UnhandledException или Window.Close

Если у вас нет доступа к traceSource в вашем раскрытии, вы можете просто объявить его снова с помощью new TraceSource("System.Net.Sockets"); или использовать другой TraceSource, определенный в вашем App.config с теми же общими прослушивателями.

Теперь у вас есть 3 возможности:

  1. Вы можете вызвать trace.Close (). Это вызовет .Close () для всех отслеживающих прослушивателей TraceSource, включая вашего специального слушателя

  2. вы можете перебирать трассировку. Слушатели и проверять тип, чтобы найти слушателя.

  3. вы можете обратиться к своему слушателю по имени: trace.Listeners ["CustomTraceListener"]. Close ()

0 голосов
/ 06 апреля 2011

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

...