PostSharp stackoverflow方面

时间:2017-01-14 17:12:43

标签: stack-overflow postsharp

Aspect类看起来像这样:

  using System;
  using System.Collections.Generic;
  using System.Linq;
  using System.Text;
  using System.Threading.Tasks;
  using System.Diagnostics;
  using PostSharp.Aspects;

  namespace GlobalExceptionHandler
  {

[Serializable]
class MyDebugger : OnMethodBoundaryAspect
{
    public override void OnEntry(MethodExecutionArgs args)
    {
        Console.WriteLine("METHOD ENTRY: " + args.Method.Name + "(" + args.Arguments.GetArgument(0) + ")");
    }
    public override void OnException(MethodExecutionArgs args)
    {
        Console.WriteLine("Exception at: " + args.Method.Name + "()");
        args.FlowBehavior = FlowBehavior.Continue;
    }
}

}

我将mscorlib程序集的方面应用于系统命名空间,但排除了我认为导致我方面的stackoverflow的控制台类,因为它使用Console.WriteLine来打印日志。

[assembly: GlobalExceptionHandler.MyDebugger(AttributeTargetAssemblies = "mscorlib", AttributeTargetTypes = "System.Console", AttributeExclude = true, AttributePriority = 100000)]

[assembly: GlobalExceptionHandler.MyDebugger(AttributeTargetAssemblies = "mscorlib", AttributeTargetTypes = "System.*")]

我仍然得到stackoverflow异常

1 个答案:

答案 0 :(得分:0)

使用“+”添加多个字符串的方面代码中的表达式实际上是作为C#编译器对String.Concat方法的调用而发出的。因此,您可以在OnEntry

中获取此代码
Console.WriteLine(String.Concat("METHOD ENTRY: ", args.Method.Name, "(", args.Arguments.GetArgument(0), ")"));

为避免递归,您可以使用与System.String相同的方式排除System.Console类。但是,在一般情况下,最好在您的方面添加一个线程静态标志,用于停止递归调用。

[Serializable]
class MyDebugger : OnMethodBoundaryAspect
{
    [ThreadStatic]
    private static bool isLogging;

    public override void OnEntry( MethodExecutionArgs args )
    {
        if ( isLogging ) return;

        isLogging = true;
        Console.WriteLine( "METHOD ENTRY: " + args.Method.Name + "(" + args.Arguments.GetArgument( 0 ) + ")" );
        isLogging = false;
    }

    public override void OnException( MethodExecutionArgs args )
    {
        if ( isLogging ) return;

        isLogging = true;
        Console.WriteLine( "Exception at: " + args.Method.Name + "()" );
        args.FlowBehavior = FlowBehavior.Continue;
        isLogging = false;
    }
}