处理必须每x
秒运行一系列顺序方法的项目。现在我将方法包含在另一个“父方法”中,然后依次顺序调用它们。
class DoTheseThings()
{
DoThis();
NowDoThat();
NowDoThis();
MoreWork();
AndImSpent();
}
每个方法必须成功运行,而不会在下一步完成之前抛出异常。所以现在我用while
和try..catch
包装每个方法,然后在catch
再次执行该方法。
while( !hadError )
{
try
{
DoThis();
}
catch(Exception doThisException )
{
hadError = true;
}
}
这看起来很臭,而且不是很干。有没有更好的方法来做到这一点,所以我没有在相同的方法中包装任何新的功能。是不是某种Delegate集合实现这个的正确方法?
是否有更“正确”的解决方案?
答案 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);
}