2012-05-24 8 views
5

Ci sono volte in cui un metodo deve essere eseguito più volte finché non viene convalidato. Nel mio caso ci sono espressioni come bar.Name.Equals("John Doe") che voglio eseguire ed eseguire fino a quando questa espressione non viene convalidata.Passa a bool Foo (params []) come metodo Argomento

Qualcosa di simile:

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

dove TryUntillOk sarebbe un metodo che gestisce questa espressione 15 volte con un sonno di 100 ms tra ogni chiamata.

Ho letto questo excelent elenco di risposte a problemi simili, ma nel mio caso non esiste un delegato standar che questo metodo TryUntillOk accetti.

Il titolo della domanda non è costruttivo. Sentiti libero di modificarla :)

+0

Questo dovrebbe essere eseguito in una discussione separata? Altrimenti non ci sarà alcuna possibilità che il valore cambi. –

+0

@GeorgeDuckett SÌ. Mi dispiace per non averlo menzionato. – Odys

risposta

8

Probabilmente si sta cercando qualcosa di simile:

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

che sarebbe invocata come segue:

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

L'unica parte interessante è che si specifica la condizione come Func<bool>, che è un delegato a un metodo che non accetta parametri e restituisce un valore booleano. La sintassi di espressione di Lambda consente di costruire banalmente tale delegato sul sito di chiamata.

+0

Probabilmente si dovrebbe notare che questo si basa su qualcosa di esterno (thread separato, ecc.) Che fa sì che la condizione venga valutata su true. –

+0

@GeorgeDuckett scusa per non averlo menzionato. Tutto ciò sarebbe stato fatto in thread di lavoro – Odys

0

Si può controllare

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

Devi adattare l'invocazione. @ La risposta di Jon ha lambda invoaction, questa versione separa il confronto dal delegato

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

Esattamente questo è stato il mio primo tentativo. Più tardi mi sono reso conto che ci potevano essere diversi metodi da chiamare, nel senso che avevo dovuto dichiarare così tanti delegati che è qualcosa che voglio evitare. – Odys

+1

... che è esattamente quello che risolve la versione lambda! –