Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/299.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 检测“控制流”何时退出类_C#_Aop_Postsharp - Fatal编程技术网

C# 检测“控制流”何时退出类

C# 检测“控制流”何时退出类,c#,aop,postsharp,C#,Aop,Postsharp,假设我有一个代码: class Module1 { public static void Main(string[] args) { Module1.level1(); } public static void level1() { Module1.level2(); } public static void level2() { Module2.level1(); } } [DetectWhenF

假设我有一个代码:

class Module1 {
    public static void Main(string[] args) {
        Module1.level1();
    }
    public static void level1() {
        Module1.level2();
    }
    public static void level2() {
        Module2.level1();
    }
}

[DetectWhenFlowExitsClass]   // <-- note aspect
class Module2 {
    public static void level1() {
        Module2.level2();
    }
    public static void level2() {
        Module2.level3();
    }
    public static void level3() {
        throw new SystemException("oops");
    }
}
问题: 如何编写检测控制流退出Module2类代码时刻的方面? 也就是说,当Test.Module2.level1完成其工作时[此处,由于异常]


在PostSharp中是否存在此方面的快捷方式?

最基本的方法是使用OnMethodBoundaryAspect,它允许您处理方法输入和方法输出建议。您需要计算堆栈上每个特定类的方法数,当该计数从1变为0时,控件将保留aspected类的方法

以下是示例方面代码:

[Serializable]
public class DetectWhenFlowExitsClass : OnMethodBoundaryAspect
{
    [ThreadStatic] private static Dictionary<Type, int> stackCounters;

    private Type declaringType;

    public override bool CompileTimeValidate(MethodBase method)
    {
        declaringType = method.DeclaringType;
        return true;
    }

    private void EnsureStackCounters()
    {
        if (stackCounters == null)
            stackCounters = new Dictionary<Type, int>();
    }

    public override void OnEntry(MethodExecutionArgs args)
    {
        EnsureStackCounters();

        int counter;

        stackCounters.TryGetValue(declaringType, out counter);
        stackCounters[declaringType] = ++counter;
    }

    public override void OnExit(MethodExecutionArgs args)
    {
        EnsureStackCounters();

        int counter;

        stackCounters.TryGetValue(declaringType, out counter);
        stackCounters[declaringType] = --counter;

        if (counter == 0)
            Console.WriteLine("Control leaving class {0}", declaringType.Name);
    }
}

您可能需要稍微修改一下这个方面的实现,但它可以在基本情况下工作。

当堆栈包含level2、level2、level1、level2时该怎么办?代码路径在逻辑上不“属于一个类”。检查为什么要这样做,它似乎关闭了。我需要它,因为在异常之后,我想记录最终的对象状态。但我现在认为这是一种错误的做法。从引发异常的第一个方法退出时应记录对象状态[此处为Module2.level3]。日志记录进一步退出[即来自方法:Module.level2 level1]应该被忽略。@Steve注意,这个问题用AOP和PostSharp标记。PostSharp在程序集中搜索称为方面的特殊属性,这些属性告诉程序集如何更改程序集。因此,你的评论与此无关。@DanielBals:好主意。虽然我不得不改变方法。反正是Tnx。
[Serializable]
public class DetectWhenFlowExitsClass : OnMethodBoundaryAspect
{
    [ThreadStatic] private static Dictionary<Type, int> stackCounters;

    private Type declaringType;

    public override bool CompileTimeValidate(MethodBase method)
    {
        declaringType = method.DeclaringType;
        return true;
    }

    private void EnsureStackCounters()
    {
        if (stackCounters == null)
            stackCounters = new Dictionary<Type, int>();
    }

    public override void OnEntry(MethodExecutionArgs args)
    {
        EnsureStackCounters();

        int counter;

        stackCounters.TryGetValue(declaringType, out counter);
        stackCounters[declaringType] = ++counter;
    }

    public override void OnExit(MethodExecutionArgs args)
    {
        EnsureStackCounters();

        int counter;

        stackCounters.TryGetValue(declaringType, out counter);
        stackCounters[declaringType] = --counter;

        if (counter == 0)
            Console.WriteLine("Control leaving class {0}", declaringType.Name);
    }
}