2012-04-12 6 views
1

私は何をしようとしているのかの簡単な例を提供するつもりです - うまくいけばそれは可能ですか?イベントまたは..を使用したクラス実行からの復帰?

私は基本的に、データの書式化/解析を一貫して行うクラスを持っています。その結果、これで間違っていることがたくさんあります。私が持っている問題は、状況が悪くなったときにクラスを処理することです。エラーが発生すると、このクラスのすべての実行を停止します。

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

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

だからここにこのコードでは、私は次の操作を行います。この「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); 
    } 
} 
} 

、私はこのクラスの実行を停止する(ループを停止し、他に何もしません)。他の親フォームでこのイベントハンドラをキャッチすることもできます。残念ながら、私はこのクラスの実行を停止する方法を見つけることができません。

アイデアこれまで:

  1. 明白な答えは単純にフラグを設定し、常に複数の場所で何度もこのフラグをチェックすることですが、私は本当にこのアプローチを好きではない(私の現在の実装) 。単一のメソッド呼び出しのたびにこれをチェックしなければならないのは、コードが醜いからです。

  2. 私はバックグラウンドワーカーやDoWorkの実行を取り消すことができると思っていましたか?

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

この状況にはどのようなアプローチが最適ですか?これらは最高のソリューションですか?私がここで欲しいものに他のエレガントな解決策があるのですか、まったく間違った方向に進んでいますか?

編集:私は、発生する可能性のあるさまざまなエラーを処理するために使用される一連のtry/catchブロックをこのコードで使用しています。残念ながら、それらのすべてが即座に捕らえる必要があるため、中止が発生するとは限りません。したがって、最も理想的なアプローチではなく、試してみてください。そうでしょうか?

答えて

2

コンストラクタで分析をしないでください。メインの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; 

しかし、あなたは多くのリターンステートメントや多くの中カッコで終わります。それはスタイルと好みの問題です。

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; 
} 
} 

あなたのイベントを使用することはもちろん可能です。私はそれを簡単にするために削除しました。

+0

有効な解決策。私がそれに関して持っている問題は、起こりうる他の例外を拾うために一連のtryとcatchを使うことだけです。私がABORTを起こすことを望むわけではありません。 – ImGreg

+0

例外を使用しないで別の方法で回答を更新しました。 –

関連する問題