繁体   English   中英

如果执行期间变量值之一变为真,则退出 C# 函数执行

[英]exiting C# function execution if one of the variable value during execution becomes true

我有一个函数 Parent() 和一个默认值为 true 的布尔类属性监视。 这个 fn Parent() 正在调用几个 Child 函数。 让我们假设在执行此函数或任何子函数期间 Watch 将其值更改为 false ,我希望执行停止并退出父函数。 父母返回无效。

这是单线程执行,没有使用异步和任务构造

我认为最简单的方法是为此使用异常:

public class TestClass
{

    public void ParentMethod()
    {
        try
        {
            ChildMethod1();
            ChildMethod2();
        }
        catch (InvalidStateException ise)
        {
            return;
        }
    }

    public void ChildMethod1()
    {
        //do stuff, and then if the "watch" is set to true:
        throw new InvalidStateException();
    }

    public void ChildMethod2()
    {
        //do stuff, and then if the "watch" is set to true:
        throw new InvalidStateException();
    }
}

public class InvalidStateException : Exception { }

在这里,我定义了一个新的异常InvalidStateException ,当ChildMethodX希望父方法停止执行时,它可以引发。 在父方法中,您尝试/捕获所有子调用,当抛出时,它会停止执行并跳到捕获中。

注意:异常发生是因为发生了异常。 如果您期望这将是正常的逻辑流程,那么我恳请您尝试一些避免异常的方法。 例外是昂贵的性能明智的。 例如,在不使用异常的情况下,您可以执行以下操作:

public class TestClass
{
    public bool Watch { get; set; }

    public void ParentMethod()
    {
        Func<bool> c1Call = () => { Child1Method(); return Watch; };
        Func<bool> c2Call = () => { ChildMethod2(); return Watch; };

        if (c1Call())
            return;

        if (c2Call())
            return;
    }

    public void Child1Method()
    {
        //Do something, then this happens:
        Watch = true;
    }

    public void ChildMethod2()
    {
        //Do something, then maybe this happens:
        Watch = true;
    }
}

您可以在哪里修改Func<>委托以接受任意数量的参数。 有十几种方法可以给这只猫剥皮,但几乎所有方法都涉及在调用函数后检查标志以确定是否要退出。 如果您的函数返回void ,请考虑将它们更改为 return bool 以便您可以执行以下操作:

if (ChildMethod1()) return;

这是非常简洁的。 否则,您可以使用 lambda 和委托的奇怪组合,但是当您深入了解它时,您必须问自己,避免键入几个额外的“if”语句是否值得损失代码可维护性?

这是一个演示模型,演示如何构建它。 它演示了一个工作流,其中 Child2 将变量设置为 false 并在此之后退出,因此从未执行 Child3。

但是我建议让子函数返回一个布尔值。 您对单线程应用程序的建议似乎不是一个好的设计。

public class Test
{
    public bool Watch { get; set; }

    public Test()
    {
        this.Watch = true;
    }

    public void Parent()
    {
        this.Child1();
        if(this.Watch == false)
        {
            return;
        }
        this.Child2();
        if(this.Watch == false)
        {
            return;
        }
        this.Child3();
        if(this.Watch == false)
        {
            return;
        }
    }

    public void Child1()
    {
        //Do stuff
    }

    public void Child2()
    {
        this.Watch = false;
    }

    public void Child3()
    {
        //Do stuff
    }
}

您可以在不同的线程中执行每个子函数,并在父函数中循环监视 Watch 值,或者您可以在每次调用 Child 后检查 Watch 值。 没有代码示例或更多信息,很难回答。

fn Parent()
{
    childfn();
    if( !Watch )
        return;

}

虽然让子函数返回 bool 并检查它而不是使用类属性可能会更好。

我假设这是你的代码结构..如果我的假设是错误的,请纠正我

我还有一个问题——所有的子函数都有相同的签名? 如果是这样,我会建议基于代表的方法。 否则这里是一个简单的例子

bool Watch { get; set; }


    // Parent is control center, calling one child after another
    void Parent()
    {
        ChildOne(1);
        if (Watch == false)
            return;

        ChildTwo(1,3);
        if (Watch == false)
            return;
    }

   /// signature type 1
    void ChildOne(int a)
    {

    }

    /// signature type 2
    void ChildTwo(int a, int b)
    {
        Watch = false;
    }

如果所有函数都具有相同的签名,则此处编辑 1 是一种方法

  class ChildFuntionExecutor
    {
        public Func<int,int> ChildFuntion;
        public int Operand1;
        public void Evaluate()
        {
             ChildFuntion(Operand1);
        }
    }

    bool Watch { get; set; }


    // Parent is control center, calling one child after another
    void Parent()
    {
        // register all child functions 
        List<ChildFuntionExecutor> childFuntionQueue = new List<ChildFuntionExecutor>();
        childFuntionQueue.Add(new ChildFuntionExecutor { Operand1 = 10, ChildFuntion = this.ChildOne });
        childFuntionQueue.Add(new ChildFuntionExecutor { Operand1 = 10, ChildFuntion = this.ChildOne });


        foreach (var item in childFuntionQueue)
        {
            item.Evaluate();
            if (Watch == false)
                return;
        }
    }

    /// signature type 1
    int ChildOne(int a)
    {
        return a * 10;
    }

    /// signature type 1
    int ChildTwo(int a)
    {
        Watch = false;
        return a * 10;
    }

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM