1

私がやろうとしていることの簡単な例を提供するつもりです-うまくいけばそれは可能ですか?

私は基本的に、データのフォーマット/分析を大量に行うクラスを持っています。結果として、これでうまくいかないことがたくさんあります。私が抱えている問題は、問題が発生したときにクラスを処理することです。エラーが発生したら、このクラスのすべての実行を停止したいと思います。

このクラス(AnalyzingStuff)は、このクラスの実行結果に基づいてさまざまなことを行う親フォームから呼び出されます。

理想的には、「ABORT」という名前のイベントを発生させます。

したがって、このコードでは、次のことを行います。

Class AnalyzingStuff{

public event EventHandler ABORT;

public AnalyzingStuff(){

    for(int i = 0; i < 999999; i ++){
        AnalyzeSomeStuff();
        AnalyzerSomeOtherStuff();
    }
    MoreStuff();
    OtherStuff();
}

private void AnalyzeSomeStuff(){
   if(someconditionNotMet){
        //EXIT OUT OF THIS CLASS, STOP EXECUTION!!!
        this.ABORT.Invoke(this, null);
   }
}
}

この「ABORT」イベントを呼び出すと、このクラスの実行を停止します(ループを停止し、他には何もしません)。このイベントハンドラーを他の親形式でキャッチすることもできます。残念ながら、このクラスの実行を停止する方法が見つかりません。

これまでのアイデア:

  1. 明白な答えは、単にフラグを設定し、このフラグを複数の場所で何度も何度もチェックすることですが、私はこのアプローチ(私の現在の実装)が本当に好きではありません。すべてのメソッド呼び出し(多数あります)の後にこれをチェックする必要があるのは、コード的には醜いです。

  2. バックグラウンドワーカーか、DoWorkの実行をキャンセルできるものかと思いました。

  3. AnalyzingStuffの基本クラスとしてフォームを使用すると、「this.Close();」を簡単に呼び出すことができます。

この状況への最善のアプローチは何だと思いますか?これらは最良の解決策ですか?私がここで欲しいものに対する他のエレガントな解決策はありますか、それとも私は完全に間違った方向に進んでいますか?

編集:発生する可能性のあるさまざまなエラーを処理するために使用される、このコード全体で使用される一連のtry/catchブロックがあります。残念ながら、それらのすべてが中絶の発生を要求しているわけではないので、すぐに捕まえる必要があります。したがって、試して/キャッチするのは最も理想的なアプローチではありません。

4

2 に答える 2

2

コンストラクターでanalysysを実行しないでください。メインのAnalyze()メソッドで実行します。

例外を使用します。致命的なエラーが原因で中止する場合は、致命的な例外をスローします。つまり、メインの分析メソッドの範囲内でキャッチされない例外をスローします。

class Analyzer
{
    public Analyzer()
    {
        // initialize things                
    }

    public void Analyze()
    {
        // never catch a fatal exception here
        try
        {
            AnalyzeStuff();
            ... optionally call more methods here ...
        }
        catch (NonFatalException e)
        {
            // handle non fatal exception
        }

        ... optionally call more methods (wrapped in try..catch) here ...
    }

    private void AnalyzeStuff()
    {
        // do stuff
        if (something nonfatal happens)
            throw new NonFatalException();

        if (something fatal happens)
            throw new FatalException();
    }
}

外側:

{
    var analyzer = new Analyzer();
    try
    {
        analyzer.Analyze();
    }
    catch (FatalException)
    {
        Console.WriteLine("Analysis failed");
    }
}

このように例外を使用したくない場合は、すべての分析メソッドにブール値を返すようにすることで、同じことを実行できます。

if (!AnalyzeStuff())
    return false;
if (!AnalyzeMoreStuff())
    return false;
...
return true;

しかし、多くのreturnステートメントまたは多くの中括弧が必要になります。それはスタイルと好みの問題です。

于 2012-04-12T21:44:29.503 に答える
1

問題が発生した場合に例外をスローし、ループ内のメソッドを呼び出す場所でtry catchを実行できますか?

これを行うと、クラスが失敗した場合に処理を実行でき(キャッチに入れます)、実行が完了したときにデータベース++への接続を閉じるために実行できる処理を実行できます。

または、メソッドがintを返すようにして、メソッドの実行が有効かどうかを確認することもできます。元。0を返します。が有効な実行である場合、1-500を返すと異なるエラーコードになる可能性があります。または、ブール値を渡すという単純なバージョンを選択することもできます。エラーコード以外のメソッドから値を返す必要がある場合は、これらをOUT変数として渡すことができます。次の例:

Class AnalyzingStuff{

public AnalyzingStuff(){

    for(int i = 0; i < 999999; i ++){
        if (!AnalyzeSomeStuff() || !AnalyzerSomeOtherStuff())
            break;
    }
    MoreStuff();
    OtherStuff();
}

private bool AnalyzeSomeStuff(){
   if(someconditionNotMet){
       return false;
   }
return true;
}
}

もちろん、イベントを使用することもできます。簡単にするために削除しました。

于 2012-04-12T20:51:01.493 に答える