为什么Type.GetInterfaces()有时不返回有效列表?

nat*_*vin 6 c# reflection wcf

我们继承了一个设计不太好的WCF服务,我们希望改进它.它的一个问题是它有超过一百种方法(在两个不同的接口上),其中大多数我们怀疑没有使用.我们决定对每种方法进行一些记录,以跟踪它们何时以及如何被调用.为了使跟踪代码重构友好且防止错误,我们实现了它:

public void LogUsage()
{
    try
    {
        MethodBase callingMethod = new StackTrace().GetFrame(1).GetMethod();
        string interfaceName = callingMethod.DeclaringType.GetInterfaces()[0].Name;
        _loggingDao.LogUsage(interfaceName, callingMethod.Name, GetClientAddress(), GetCallingUrl());
    }
    catch (Exception exception)
    {
        _legacyLogger.Error("Error in usage tracking", exception);
    }
}
Run Code Online (Sandbox Code Playgroud)

LogUsage() 然后在我们想要跟踪的每个方法的开头调用.

该服务的流量非常高,每天有500,000多个电话.99.95%的时间,这段代码执行得很漂亮.但另外0.05%的时间,GetInterfaces()返回一个空(但不是null)数组.

为什么GetInterfaces()偶尔会返回不一致的结果?

这似乎是微不足道的 - 0.05%的错误率是我们通常只能梦想的.但重点是识别所有服务接触点,如果此错误总是来自一个(或几个)方法调用,那么我们的跟踪是不完整的.我试图通过调用服务上的每个方法在我的开发环境中重现此错误,但无济于事.

Gre*_*Ros 4

StackTrace众所周知,它是不可靠的,尤其是在多线程环境中。或者更确切地说,它非常可靠,但有时不太实用。询问“最后调用的方法”可能会产生意想不到的结果。尝试记录 DeclaringType。您可能会对在那里发现的东西感到惊讶。请注意,虽然现在故障率为 0.05%,但它可能会随着应用程序的复杂性而轻松增加。

为了正确实现可重用的跟踪代码,您需要依靠 .NET 4.5 功能Caller Information、使用动态代理(例如Castle Dynamic Proxy)或使用 AOP 框架(例如PostSharp)。或者,您也可以手动编写跟踪代码。