2012-05-24 29 views
5

有時候需要多次運行一個方法直到它被驗證。在我的情況下,有像bar.Name.Equals("John Doe")這樣的表達式,我想運行並運行,直到此表達式生效。作爲方法傳遞bool Foo(params [])參數

是這樣的:

bool succeeded = TryUntillOk(bar.Name.Equals("John Doe"), 15, 100); 

其中TryUntillOk將是與100ms的每個調用之間的睡眠運行此表達15倍的方法。

我看過這個excelent類似問題的答案列表,但在我的情況下沒有標準代表,這個TryUntillOk方法會接受。

問題的標題不具有建設性。隨意編輯:)

+0

這會在單獨的線程中運行嗎?否則,價值不會有任何改變的機會。 –

+0

@GeorgeDuckett是的。對不起,不提。 – Odys

回答

8

您可能正在尋找這樣的事情:

bool TryRepeatedly(Func<bool> condition, int maxRepeats, TimeSpan repeatInterval) 
{ 
    for (var i = 0; i < maxRepeats; ++i) 
    { 
     if (condition()) return true; 
     Thread.Sleep(repeatInterval); // or your choice of waiting mechanism 
    } 
    return false; 
} 

這將調用如下:

bool succeeded = TryRepeatedly(() => bar.Name.Equals("John Doe"), 
           15, 
           TimeSpan.FromMilliseconds(100)); 

這裏唯一有趣的部分是您指定條件爲Func<bool>,它是不接受任何參數並返回布爾值的方法的委託。 Lambda表達式語法允許您在調用站點平凡地構造這樣的委託。

+0

它應該指出,這依賴於某些外部(單獨的線程等),導致條件最終評估爲真。 –

+0

@GeorgeDuckett抱歉沒有提到這一點。所有這些都將在工作線程中完成 – Odys

0

你可以檢查一下

delegate void d_name(string s); 

d_name obj =new d_name(bar.Name.Equals); 

bool succeeded = TryUntillOk(obj("John Doe"), 15, 100); 

TryUntillOk(obj d,type parameter2,type parameter3) 
{ 
    //do your work 
} 
1

你必須適應invokation。 @ Jon的答案有lambda invoaction,這個版本將比較從委託中分離出來

using System; 
using System.Threading; 

namespace test 
{ 
    class something 
    { 
     public String Name; 
    } 

    class Program 
    { 
     private delegate bool TryableFunction(String s); 

     private static bool TryUntillOk(TryableFunction f, String s, int howoften, int sleepms) 
     { 
      while (howoften-->0) 
      { 
       if (f(s)) return true; 
       Thread.Sleep(sleepms); 
      } 
      return false; 
     } 

     static void Main(string[] args) 
     { 
      something bar=new something(); 

      bar.Name="Jane Doe"; 
      bool succeeded = TryUntillOk(bar.Name.Equals,"John Doe", 15, 100); 
      Console.WriteLine("Succeeded with '{0}': {1}",bar.Name,succeeded); 

      bar.Name="John Doe"; 
      succeeded = TryUntillOk(bar.Name.Equals,"John Doe", 15, 100); 
      Console.WriteLine("Succeeded with '{0}': {1}",bar.Name,succeeded); 
     } 


    } 
} 
+0

準確地說,這是我的第一次嘗試。後來我意識到可能有幾種方法可以調用,這意味着我不得不宣佈如此多的代表,這是我想避免的。 – Odys

+1

......這正是lambda版本解決的問題! –