2008-10-25 158 views
4

在每個x秒必須運行一組順序方法的項目上工作。現在我已經將方法包含在另一個「父方法」中,並且只是按順序將它們連續調用。執行順序方法的最佳方法是什麼?

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

每個方法必須在下一步可以完成之前成功運行而不會拋出異常。所以現在我用whiletry..catch包裝每個方法,然後在catch再次執行該方法。

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

} 

這看起來很臭,不是很乾燥。有沒有更好的方法來做到這一點,所以我不用相同的方法包裝任何新的功能。是不是某種Delegate集合實現這個的正確方法?

有沒有更合適的解決方案?

回答

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 
    } 
} 
+0

任何理由不只是使用內置的Action委託? – 2008-10-25 23:58:03

+0

如果您發現需要評論「SimpleDelegate」,那肯定應該是它自己的名字。 – 2008-10-26 00:16:16

+0

如果它失敗,它需要重新運行該操作。 – nyxtom 2008-10-26 00:19:19

0

錯誤發生的原因是什麼?

如果這是一個資源問題,如獲得類似的連接或對象,那麼你可能想看看使用顯示器,信號量,或者只是鎖定。

lock (resource) 
{ 
    Dosomething(resource); 
} 

這樣,如果以前的方法訪問資源,那麼你可以等到它釋放資源以繼續。

理想情況下,你不應該運行一個循環每次失敗的時間來執行的東西。這是失敗的,你會想知道這個問題並修復它。有一個循環往往只是繼續嘗試不是正確的方式去這裏。

2

是不是某種代表收集來實現這種正確的方法是什麼?

代表是解決這一問題的一個可行的辦法。

只需創建一個委託是這樣的:

公衆委託無效WorkDelegate();

,並把他們的ArrayList中,你可以遍歷。

0

我想做Ovidiu Pacurar建議的事情,只使用foreach循環,並將數組索引交給編譯器處理。

1

您的例子似乎確定..其乾燥之一,但會做的工作做好!實際上,如果這個方法執行DB訪問..你可以使用事務,以確保其完整性...

如果你對付的多穿線程序共享變量..它是清潔劑使用同步。在編碼中最重要的事情是你寫出了正確的代碼......這樣有更少的錯誤,並且會正確地完成任務。

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

相關問題