C# 抑制来自特定DLL的跟踪消息

C# 抑制来自特定DLL的跟踪消息,c#,visual-studio,C#,Visual Studio,我使用的是第三方库,它对函数进行了多次调用: Trace.WriteLine(string message); 这会使VisualStudio输出窗口变得混乱,使调试应用程序变得困难(例如,XAML绑定警告) 我正在试图找到一种方法来阻止来自特定dll的所有跟踪消息转储到visual studio输出窗口-编写自己的跟踪侦听器是唯一的前进路径吗 我无法使TraceFilter/EventTypeFilter对没有类别的字符串消息起作用——尽管我找不到支持这一点的文档——根据经验: Trace

我使用的是第三方库,它对函数进行了多次调用:

Trace.WriteLine(string message);
这会使VisualStudio输出窗口变得混乱,使调试应用程序变得困难(例如,XAML绑定警告)

我正在试图找到一种方法来阻止来自特定dll的所有跟踪消息转储到visual studio输出窗口-编写自己的跟踪侦听器是唯一的前进路径吗


我无法使TraceFilter/EventTypeFilter对没有类别的字符串消息起作用——尽管我找不到支持这一点的文档——根据经验:

TraceFilter.ShouldTrace(...)
由以下函数调用(不是完整的集合):

但不是由以下人员调用:

Trace.WriteLine(string message);
有人知道为什么此调用会避免ShouldTrace筛选器吗?

根据,Trace.WriteLine(字符串消息)声明为抽象,需要由派生类重写:

public abstract void WriteLine(string message);
您提到的所有其他方法都会检查
ShouldTrace
,并最终调用
Trace.WriteLine(字符串消息)
消息

例如:

所以我认为真正的原因是,
Trace
类的设计者的决定

他可以将
Trace.WriteLine(字符串消息)
保护到不打算直接调用的程度,例如:

protected abstract void WriteLine(string message);
根据,Trace.WriteLine(字符串消息)声明为抽象,需要由派生类重写:

public abstract void WriteLine(string message);
您提到的所有其他方法都会检查
ShouldTrace
,并最终调用
Trace.WriteLine(字符串消息)
消息

例如:

所以我认为真正的原因是,
Trace
类的设计者的决定

他可以将
Trace.WriteLine(字符串消息)
保护到不打算直接调用的程度,例如:

protected abstract void WriteLine(string message);
  • 如果您不想创建自己的
    TraceListener
    ,则禁止问题dll中的
    Trace
    消息的唯一方法是使用
    Trace.Listeners.Clear()
    停止所有
    Trace
    消息 请注意,这也将停止您自己的
    跟踪
    调用。我之所以提到这一点,是因为我知道有几个应用程序从未使用过Trace.WriteLine,并且由于一个非常嘈杂的库不断写入输出窗口,性能受到严重影响

  • 我建议创建一个
    TraceListener
    ,它使用反射在调用堆栈中查找要忽略的dll
  • 无法覆盖
    Trace.WriteLine
    ,但可以覆盖默认
    TraceListener
    中的某些调用以实现相同的效果

    使用像下面这样的
    TraceListener
    可以帮助您清理Visual Studio中的输出窗口,这样您就可以专注于感兴趣的事件,而不是被来自第三方库的消息轰炸

    请参见下面的示例代码:

    using System;
    using System.Diagnostics;
    using System.Reflection;
    
    // The library that calls Trace, causing the messages you want to suppress.
    using NoisyLibrary;
    
    namespace TraceSuppress
    {
        /// <summary>
        /// Trace listener that ignores trace messages from a specific assembly.
        /// </summary>
        public class AssemblyFilteredListener : DefaultTraceListener
        {
            private Assembly assemblyToIgnore;
    
            public AssemblyFilteredListener(Assembly assemblyToIgnoreTracesFrom)
            {
                this.assemblyToIgnore = assemblyToIgnoreTracesFrom;
            }
    
            public bool TraceIsFromAssemblyToIgnore()
            {
                StackTrace traceCallStack = new StackTrace();
    
                StackFrame[] traceStackFrames = traceCallStack.GetFrames();
    
                // Look for the assembly to ignore in the call stack.
                //
                // This may be rather slow for very large call stacks. If you find that this is a bottleneck
                // there are optimizations available.
                foreach (StackFrame traceStackFrame in traceStackFrames)
                {
                    MethodBase callStackMethod = traceStackFrame.GetMethod();
    
                    bool methodIsFromAssemblyToIgnore = (callStackMethod.Module.Assembly == this.assemblyToIgnore);
    
                    if (methodIsFromAssemblyToIgnore)
                    {
                        return true;
                    }
    
                }
    
                // The assembly to ignore was not found in the call stack.
                return false;         
    
            }
    
    
            public override void WriteLine(string message)
            {
                if (!this.TraceIsFromAssemblyToIgnore())
                {
                    base.WriteLine(message);
                }
            }         
    
            public override void Write(string message)
            {
                if (!this.TraceIsFromAssemblyToIgnore())
                {
                    base.Write(message);
                }
            }
        }
    
        class Program
        {
            static void SetupListeners()
            {
                // Clear out the default trace listener
                Trace.Listeners.Clear();
    
                // Grab the asssembly of the library, using any class from the library.
                Assembly assemblyToIgnore = typeof(NoisyLibrary.LibraryClass).Assembly;
    
                // Create a TraceListener that will ignore trace messages from that library
                TraceListener thisApplicationOnlyListener = new AssemblyFilteredListener(assemblyToIgnore);
    
                Trace.Listeners.Add(thisApplicationOnlyListener);
    
                // Now the custom trace listener is the only listener in Trace.Listeners.
            }
    
            static void Main(string[] args)
            {
                SetupListeners();            
    
                // Testing
                //-------------------------------------------------------------------------
    
                // This still shows up in the output window in VS...
                Trace.WriteLine("This is a trace from the application, we want to see this.");
    
                // ...but the library function that calls trace no longer shows up.
                LibraryClass.MethodThatCallsTrace();
    
                // Now check the output window, the trace calls from that library will not be present.
    
            }
        }
    }
    
    使用系统;
    使用系统诊断;
    运用系统反思;
    //调用跟踪的库,导致要抑制的消息。
    使用噪声库;
    命名空间跟踪支持
    {
    /// 
    ///忽略来自特定程序集的跟踪消息的跟踪侦听器。
    /// 
    公共类AssemblyFilteredListener:DefaultTraceListener
    {
    私人集会;
    public AssemblyFilteredListener(Assembly assemblyToIgnoreTracesFrom)
    {
    this.assemblyToIgnore=assemblyToIgnoreTracesFrom;
    }
    公共布尔跟踪FromAssemblyToIgnore()
    {
    StackTrace traceCallStack=新StackTrace();
    StackFrame[]traceStackFrames=traceCallStack.GetFrames();
    //在调用堆栈中查找要忽略的程序集。
    //
    //对于非常大的调用堆栈,这可能相当慢。如果您发现这是一个瓶颈
    //有可用的优化。
    foreach(traceStackFrames中的StackFrame traceStackFrame)
    {
    MethodBase callStackMethod=traceStackFrame.GetMethod();
    bool方法是FromAssemblyToIgnore=(callStackMethod.Module.Assembly==this.assemblyToIgnore);
    如果(方法是从组装到点火)
    {
    返回true;
    }
    }
    //在调用堆栈中找不到要忽略的程序集。
    返回false;
    }
    公共覆盖无效写线(字符串消息)
    {
    如果(!this.TraceIsFromAssemblyToIgnore())
    {
    base.WriteLine(消息);
    }
    }         
    公共重写无效写入(字符串消息)
    {
    如果(!this.TraceIsFromAssemblyToIgnore())
    {
    base.Write(消息);
    }
    }
    }
    班级计划
    {
    静态void SetupListeners()
    {
    //清除默认跟踪侦听器
    Trace.Listeners.Clear();
    //使用库中的任何类获取库的组合。
    Assembly assemblyToIgnore=typeof(noiselibrary.LibraryClass).Assembly;
    //创建一个TraceListener,它将忽略来自该库的跟踪消息
    TraceListener thisApplicationOnlyListener=新的AssemblyFilteredListener(assemblyToIgnore);
    Trace.Listeners.Add(thisApplicationOnlyListener);
    //现在,自定义跟踪侦听器是trace.Listeners中唯一的侦听器。
    }
    静态void Main(字符串[]参数)
    {
    SetupListeners();
    //测试
    //-------------------------------------------------------------------------
    //这仍然显示在VS…的输出窗口中。。。
    WriteLine(“这是来自应用程序的跟踪