2012-05-24 13 views
5

Es gibt Zeiten, in denen eine Methode mehrmals ausgeführt werden muss, bis sie überprüft wird. In meinem Fall gibt es Ausdrücke wie bar.Name.Equals("John Doe"), die ich ausführen und ausführen möchte, bis dieser Ausdruck validiert.Übergeben Sie ein bool Foo (params []) als Methode Argument

Etwas wie:

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

wo TryUntillOk wäre eine Methode, die diesen Ausdruck 15-mal mit einem Schlaf von 100 ms zwischen jedem Anruf läuft.

Ich lese diese excelent Liste der Antworten auf ähnliche Probleme, aber in meinem Fall gibt es keinen Standardbeauftragten, dass diese TryUntillOk Methode akzeptieren würde.

Der Titel der Frage ist nicht konstruktiv. Fühlen Sie sich frei zu bearbeiten :)

+0

Würde dies in einem separaten Thread ausgeführt werden? Sonst gibt es keine Chance, dass sich der Wert ändert. –

+0

@GeorgeDuckett JA. Entschuldige, dass ich es nicht erwähnt habe. – Odys

Antwort

8

Sie wahrscheinlich etwas suchen, wie folgt aus:

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

, die wie folgt aufgerufen werden würde:

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

Der einzige hier interessante Teil ist, dass Sie angeben, Die Bedingung als Func<bool>, die ein Delegat für eine Methode ist, die keine Parameter akzeptiert und einen booleschen Wert zurückgibt. Die Lambda-Ausdruckssyntax ermöglicht es Ihnen, einen solchen Delegaten auf der Aufrufseite trivial zu konstruieren.

+0

Es sollte wahrscheinlich bemerkt werden, dass dies auf etwas Externes (separater Thread usw.) angewiesen ist, was dazu führt, dass die Bedingung letztendlich als wahr bewertet wird. –

+0

@GeorgeDuckett Entschuldigung dafür, dies nicht zu erwähnen. All dies würde in Worker Threads getan werden – Odys

0

Sie kann

überprüfen
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

Sie haben die Invokation anzupassen. @ Jons Antwort hat Lambda-Invoiction, diese Version trennt den Comparand von dem Delegaten

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

Genau das war mein erster Versuch. Später wurde mir klar, dass es mehrere Methoden zum Anrufen geben könnte, was bedeutet, dass ich so viele Delegierte deklarieren musste, was ich vermeiden möchte. – Odys

+1

... genau das löst die Lambda-Version! –