簡體   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