2

我编写了一个扩展 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);
    }
4

3 回答 3

1

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

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");
                }
于 2011-04-08T18:31:14.060 回答
1

另一种无需反思的方法:

您在某处定义跟踪源,可能像这样:

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

现在,你仍然需要 Teardown,或者最后调用的东西。在单元测试之外,您可以捕获 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"].Close()

于 2012-05-27T13:41:40.303 回答
0

无论您的方法名称是什么,您都必须自己显式调用它。从终结器进行任何有意义的处理是非常困难的,因为当 GC 销毁收集的对象并且它不以任何特定顺序执行时,这意味着您不能依赖任何您可能希望在终结器中处理的对象仍然存在。

于 2011-04-06T17:11:35.330 回答