4

メソッドのシーケンシャル セットを毎秒実行する必要があるプロジェクトに取り組んでいますx。現在、別の「親メソッド」にメソッドが含まれており、それらを次々と順番に呼び出しています。

class DoTheseThings()
{
    DoThis();
    NowDoThat();
    NowDoThis();
    MoreWork();
    AndImSpent();
}

次のステップを実行する前に、各メソッドは例外をスローすることなく正常に実行される必要があります。whileそのため、これらの各メソッドをandでラップし、try..catchそのcatchメソッドを再度実行します。

while( !hadError )
{
    try
    {
         DoThis();
    }
    catch(Exception doThisException )
    {
         hadError = true;
    }

}

これは臭いがあり、あまり乾燥していないようです。これを行うためのより良い方法があるので、新しい機能を同じメソッドにラップしていません。これを実装する適切な方法は、ある種のデリゲート コレクションではありませんか?

もっと「適切な」解決策はありますか?

4

8 に答える 8

5
Action[] work=new Action[]{new Action(DoThis),   new Action(NowDoThat),    
    new Action(NowDoThis),    new Action(MoreWork),    new Action(AndImSpent)};
int current =0;
while(current!=work.Length)
{
   try
   {
      work[current]();
      current++;
   }
   catch(Exception ex)
   {
      // log the error or whatever
      // maybe sleep a while to not kill the processors if a successful execution depends on time elapsed  
   }
}
于 2008-10-25T22:38:04.373 に答える
2

これを実装する適切な方法は、ある種のデリゲート コレクションではありませんか?

デリゲートは、この問題を解決するための可能な方法です。

次のようなデリゲートを作成するだけです。

パブリック デリゲート void WorkDelegate();

それらを反復できるarraylistに入れます。

于 2008-10-25T22:39:22.750 に答える
2

System.Exception をキャッチしてはならないという個人的な宗教的信念があります。より正確には、処理方法を知っている例外のみをキャッチする必要があります。

そうは言っても、呼び出しているメソッドはそれぞれ異なることを行っており、異なる例外がスローされる可能性があると想定しています。つまり、メソッドごとに異なるハンドラーが必要になる可能性があります。

あなたも私の宗教に従い、2 番目のステートメントが正しい場合、コードを不必要に繰り返しているわけではありません。他の要件がない限り、コードを改善するための私の推奨事項は次のとおりです。

1) 各メソッド呼び出しの周りではなく、各メソッドに try-catch を配置します。

2)各メソッド内のキャッチで、知っている例外のみをキャッチします。

http://blogs.msdn.com/fxcop/archive/2006/06/14/631923.aspx http://blogs.msdn.com/oldnewthing/archive/2005/01/14/352949.aspx http:// www.joelonsoftware.com/articles/Wrong.html

HTH ...

于 2008-10-26T01:01:38.190 に答える
1

あなたの例は大丈夫のようです..それは乾燥したものですが、うまくいくでしょう!! 実際、このメソッドがdbアクセスを実行する場合、トランザクションを使用して整合性を確保できます。

マルチスレッダープログラムの共有変数を扱う場合は、同期を使用する方がクリーンです。コーディングで最も重要なことは、バグが少なく、タスクを正しく実行する適切なコードを作成することです。

于 2008-10-25T23:29:23.787 に答える
1
public void DoTheseThings()
{
    SafelyDoEach( new Action[]{
        DoThis,
        NowDoThat,
        NowDoThis,
        MoreWork,
        AndImSpent
    })
}

public void SafelyDoEach( params Action[] actions )
{
    try
    {
        foreach( var a in actions )
            a();
    }
    catch( Exception doThisException )
    {
        // blindly swallowing every exception like this is a terrible idea
        // you should really only be swallowing a specific MyAbortedException type
        return;
    }
}
于 2008-10-26T00:14:36.020 に答える
0

私は Ovidiu Pacurar が提案することを行いますが、foreachループを使用して配列インデックスの処理をコンパイラに任せるだけです。

于 2008-10-25T22:44:20.960 に答える
0

シンプルなデリゲート アプローチ:

Action<Action> tryForever = (action) => { 
   bool success;
   do {
     try {
       action();
       success = true;
     } catch (Exception) {
       // should probably log or something here...
     }
   } while (!success);
};

void DoEverything() {
   tryForever(DoThis);
   tryForever(NowDoThat);
   tryForever(NowDoThis);
   tryForever(MoreWork);
   tryForever(AndImSpent);
}

スタック アプローチ:

void DoEverything() {
  Stack<Action> thingsToDo = new Stack<Action>(
    new Action[] { 
      DoThis, NowDoThat, NowDoThis, MoreWork, AndImSpent 
    }
  );

  Action action;
  while ((action = thingsToDo.Pop()) != null) {
     bool success;
     do {
       try {
         action();
         success = true;
       } catch (Exception) {
       }
     } while (!success);
  }
于 2008-10-26T00:10:11.083 に答える
0

エラーが発生していた理由は何でしょうか?

これが接続やオブジェクトなどへのアクセスなどのリソースの問題である場合は、モニター、セマフォ、または単にロックを使用することを検討する必要があります。

lock (resource) 
{
    Dosomething(resource);
}

このようにして、以前のメソッドがリソースにアクセスしている場合、リソースが解放されるまで待ってから続行できます。

理想的には、失敗するたびに何かを実行するためにループを実行する必要はありません。まったく失敗しています。問題について知り、修正する必要があります。常に試行し続けるループを持つことは、ここに行く正しい方法ではありません。

于 2008-10-25T22:31:24.140 に答える