如何在c#中调用自定义跟踪侦听器上的dispose

时间:2011-04-06 16:58:26

标签: c# garbage-collection dispose finalizer tracelistener

我编写了一个自定义跟踪侦听器,扩展了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 个答案:

答案 0 :(得分:1)

我必须编写一个SetUpFixture,在TearDown中,使用一些反射从程序集中获取类型“System.Diagnostics.TraceSource”,得到一个私有静态字段,它是所有跟踪源的列表,并调用Dispose()on我的自定义监听器。

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

在TraceSource上的所有侦听器上调用Dispose()

foreach (TraceListener listener in s.Listeners)
                {
                   listener.Dispose();
                   Console.WriteLine("disposing");
                }

答案 1 :(得分:1)

另一种没有反思的方法:

你可以在某处定义你的traceource,可能是这样的:

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

现在,你仍然需要拆解,或者最后调用的东西。 在单元测试之外,您可以捕获AppDomain.ProcessExit, AppDomain.UnhandledException或Window.Close

如果您在拆解时无法访问traceSource,您可以使用new TraceSource("System.Net.Sockets");再次声明它,也可以使用App.config中定义的另一个TraceSource和相同的共享侦听器。

现在你有3种可能性:

  1. 你可以调用trace.Close()。 这将为侦听该TraceSource的所有traceListener调用.Close(),包括您的特殊侦听器

  2. 您可以遍历trace.Listeners并检查类型以找到您的监听器。

  3. 您可以通过名称引用您的侦听器:trace.Listeners [“CustomTraceListener”]。关闭()

答案 2 :(得分:0)

无论您的方法名称是什么,您都必须自己明确地调用它。从终结器进行任何有意义的处理是非常困难的,因为当GC破坏收集的对象并且它不按任何特定顺序执行时,这意味着您不能依赖于您可能想要在终结器中处理的任何对象仍然存活。