2012-12-29 27 views
1

我對C#比較陌生,也許你可以幫助我。模式/架構/匿名方法

我有幾個方法callServiceXY(param1, param2, ...)調用某種服務。由於很多原因,這些服務調用可能會出錯(我最終並不真正關心這個原因)。所以基本上我需要總是像這樣包起來 - 有,如果出現錯誤他們再次執行:

var i = 3; 
while(i>0) 
    try{ 
    call...() 
    } catch{ 
    i--; 
    } 
    i=0; 
} 

我寧願寫代碼只有一次。我能以某種方式使用像tryXtimes(int x, callService())這樣的方法,允許我執行未定義或匿名方法嗎? (我有Javascript在腦海裏,這是可能的...)?

+0

也許,門面模式可以幫助你。 –

回答

2

是的,這是可能的。 C#3.5增加了對ActionFunc<T>類型的支持。一個Action不會返回任何值,一個Func總會返回一個值。

你有幾個不同的版本,也接受一些參數。下面的控制檯應用程序介紹瞭如何能做到這一點:

using System; 

namespace Stackoverflow 
{ 
    class Service 
    { 
     public int MyMethod() { return 42; } 
     public void MyMethod(string param1, bool param2) { } 

     public int MyMethod(object paramY) { return 42; } 
    } 

    class Program 
    { 
     static void ExecuteWithRetry(Action action) 
     { 
      try 
      { 
       action(); 
      } 
      catch 
      { 
       action(); 
      } 

     } 

     static T ExecuteWithRetry<T>(Func<T> function) 
     { 
      try 
      { 
       return function(); 
      } 
      catch 
      { 
       return function(); 
      } 

     } 

     static void Main(string[] args) 
     { 
      Service s = new Service(); 
      ExecuteWithRetry(() => s.MyMethod("a", true)); 

      int a = ExecuteWithRetry(() => s.MyMethod(1)); 
      int b = ExecuteWithRetry(() => s.MyMethod(true)); 

     } 
    } 
} 

正如你所看到的,有兩個重載ExecuteWithRetry。一個返回的void,一個返回一個類型。您可以撥打ExecuteWithRetry,通過ActionFunc

- >編輯:太棒了!只是一點點額外的代碼來完成這個例子:

使用匿名函數/方法:

ExecuteWithRetry(() => 
{ 
    logger.Debug("test"); 
}); 

而且隨着更多的參數(動作,INT)

方法標題:

public static void ExecuteWithRetryX(Action a, int x) 

方法調用:

ExecuteWithRetryX(() => { logger.Debug("test"); }, 2); 
+0

自.NET 2.0起,Action和Func存在。 – Tilak

1

我會爲此使用策略/工廠模式。這個答案https://stackoverflow.com/a/13641801/626442給出了使用鏈接的策略/工廠模式的例子。上述鏈接中的問題將爲您提供另一種可以採用此模式的示例。

有很多這些設計模式的例子here和以下詳細介紹了Strategy patternFactory pattern。最後兩個鏈接的前者還向您展示瞭如何將這兩個鏈接結合起來,以完成您所需要的內容。

我希望這會有所幫助。

0

嘗試以下

​​

演示here

訣竅是Action<object[]>接受對象數組和返回void並且在重試方法params關鍵字。
要返回非空值,請將Action<object[]>更改爲Func<T, object[]>