执行顺序方法的最佳方法是什么?

时间:2008-10-25 22:24:32

标签: c# exception delegates

处理必须每x秒运行一系列顺序方法的项目。现在我将方法包含在另一个“父方法”中,然后依次顺序调用它们。

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

每个方法必须成功运行,而不会在下一步完成之前抛出异常。所以现在我用whiletry..catch包装每个方法,然后在catch再次执行该方法。

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

}

这看起来很臭,而且不是很干。有没有更好的方法来做到这一点,所以我没有在相同的方法中包装任何新的功能。是不是某种Delegate集合实现这个的正确方法?

是否有更“正确”的解决方案?

8 个答案:

答案 0 :(得分: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  
   }
}

答案 1 :(得分:2)

  

是不是某种Delegate集合是实现这个的正确方法?

委托是解决此问题的可能方法。

只需创建一个类似的委托:

  

public delegate void WorkDelegate();

并将它们放入可以迭代的arraylist中。

答案 2 :(得分:2)

我有一种个人宗教信仰,你不应该捕获System.Exception,或者更确切地说,你应该只捕获你知道如何处理的异常。

话虽如此,我将假设您正在调用的每个方法都在做不同的事情,并且可能导致抛出不同的异常。这意味着您可能需要为每种方法使用不同的处理程序。

如果您也遵循我的宗教信仰,并且第二个陈述是真的,那么您不会不必要地重复代码。除非您有其他要求,否则我提出的改进代码的建议是:

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 ......

答案 3 :(得分:1)

你的例子似乎没问题......它是一个干的但是能很好地完成工作!实际上,如果此方法执行db访问..您可以使用事务来确保完整性......

如果您处理多线程程序的共享变量..使用同步更简洁..编码中最重要的是您编写正确的代码...具有较少的错误..并将执行任务正确..

答案 4 :(得分: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;
    }
}

答案 5 :(得分:0)

发生错误的原因是什么?

如果这是一个资源问题,例如访问连接或对象之类的东西,那么您可能希望查看使用监视器,信号量或只是锁定。

lock (resource) 
{
    Dosomething(resource);
}

这样,如果以前的方法正在访问资源,那么您可以等到它释放资源以继续。

理想情况下,每次失败时都不必运行循环来执行某些操作。它完全失败了,你想知道这个问题并解决它。有一个循环,总是只是继续尝试不是正确的方式去这里。

答案 6 :(得分:0)

我会做Ovidiu Pacurar所建议的,只有我使用foreach循环并将数组索引处理到编译器。

答案 7 :(得分: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);
  }