将TraceListener添加/删除到所有TraceSources

Hug*_*une 17 c# logging trace .net-3.5 tracelistener

我正在寻找一种方法来为所有现有的TraceSources添加和删除TraceListener.

(我不确定我的方法是否正确,我可以使用其他方法?基本上我想将所有跟踪输出记录到使用当前项目名称作为文件名的文件中.每当用户创建或重新打开项目时,我想要将日志附加到正确的文件.一次只能打开一个项目.)

代码示例:

我在我的应用程序中创建了几个TraceSource,每个类一个

public class Class1
{
    private static readonly System.Diagnostics.TraceSource trace = 
            new System.Diagnostics.TraceSource("Class1");
}

public class Class2
{
    private static readonly System.Diagnostics.TraceSource trace = 
            new System.Diagnostics.TraceSource("Class2");
}
Run Code Online (Sandbox Code Playgroud)

我现在想在运行时向我的所有traceSource添加或删除traceListener,如下所示:

private System.Diagnostics.TextWriterTraceListener myListener;

private onProjectOpen()
{
    // user created a new project or opened an existing one
    myListener = new System.Diagnostics.TextWriterTraceListener("log-"+projectname+".log");
    ALL_TRACESOURCES.Add ( myListener) ; // <-- how to do this?
}

private onProjectClose()
{
    // user closed a project
    ALL_TRACESOURCES.Remove( myListener) ; // <-- how to do this?
    myListener.Flush();
    myListener.Close();
    myListener.Dispose(); // <-- not sure if all this is neccessary
}
Run Code Online (Sandbox Code Playgroud)

到目前为止,我发现如果没有公开我的所有traceSources(看起来是个坏主意),然后列出我的所有类,就没有办法做到这一点:

Class1.Trace.Add( myListener );
Class2.Trace.Add( myListener );
...
Run Code Online (Sandbox Code Playgroud)

这在几个层面上似乎是一个糟糕的设计选择.

要么

将我的所有TraceSources添加到每个类的构造函数中的自定义全局集合中(容易遗忘/搞乱;全局变量很糟糕)

有没有更好的办法?基本上我正在寻找一种方法来设置另一个默认监听器

dec*_*tes 1

在 .NET 4 及更高版本中,您可以在配置侦听器后使用Lazy<>延迟加载 TraceSource。请参阅以下工作示例程序:

public static class TraceSources
{
    public static TraceSource Create(string sourceName)
    {
        var source = new TraceSource(sourceName);
        source.Listeners.AddRange(Trace.Listeners);
        source.Switch.Level = SourceLevels.All;
        return source;
    }
}

public class Class1
{
    private static readonly Lazy<TraceSource> trace = new 
            Lazy<TraceSource>(() => TraceSources.Create("Class1"));

    public void DoSomething()
    {
        trace.Value.TraceEvent(TraceEventType.Information, 1, "Class1 speaking up");
    }
}

public class Class2
{
    private static readonly Lazy<TraceSource> trace = new
            Lazy<TraceSource>(() => TraceSources.Create("Class2"));

    public void DoSomethingElse()
    {
        trace.Value.TraceEvent(TraceEventType.Information, 2, "Class2 speaking out");
    }
}

public class Program
{
    static void Main(string[] args)
    {
        try
        {
            var listener = new TextWriterTraceListener(@"C:\trace.txt");
            Trace.Listeners.Add(listener);

            var classOne = new Class1();
            var classTwo = new Class2();
            classOne.DoSomething();
            classTwo.DoSomethingElse();
        }
        finally
        {
            Trace.Close();
        }
    }
}
Run Code Online (Sandbox Code Playgroud)