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

某种委托集合不是实现这一点的正确方法吗?

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

只需创建一个委托,例如:

公共代表无效 WorkDelegate();

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

于 2008-10-25T22:39:22.750 回答
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 ...

于 2008-10-26T01:01:38.190 回答
1

你的例子看起来不错..它是一个干燥的例子,但会做得很好!!实际上,如果此方法执行数据库访问..您可以使用事务来确保完整性...

如果您处理多线程程序的共享变量..使用同步更清洁..编码中最重要的是您编写正确的代码...错误更少..并且可以正确完成任务..

于 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

发生错误的原因是什么?

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

lock (resource) 
{
    Dosomething(resource);
}

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

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

于 2008-10-25T22:31:24.140 回答
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 回答