2012-05-24 26 views
5

Hay veces que un método necesita ejecutarse varias veces hasta que se valida. En mi caso, hay expresiones como bar.Name.Equals("John Doe") que quiero ejecutar y ejecutar hasta que esta expresión se valida.Pase un Bool Foo (params []) como método Argumento

Algo así como:

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

donde TryUntillOk habría un método que funciona esta expresión 15 veces con un sueño de 100 ms entre cada llamada.

He leído este excelent lista de respuestas a problemas similares, pero en mi caso no hay un delegado estándar que acepte este método TryUntillOk.

El título de la pregunta no es constructivo. Siéntase libre para editarla :)

+0

¿Funcionaría esto en una conversación separada? De lo contrario, no habrá ninguna posibilidad de que cambie el valor. –

+0

@GeorgeDuckett SÍ. Perdón por no haberlo mencionado. – Odys

Respuesta

8

Usted probablemente está buscando algo como esto:

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

Qué se invoca de la siguiente manera:

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

La única parte interesante aquí es que especifique la condición como Func<bool>, que es un delegado a un método que no toma parámetros y devuelve un valor booleano. La sintaxis de la expresión Lambda le permite construir trivialmente dicho delegado en el sitio de la llamada.

+0

Probablemente debería notarse que esto depende de algo externo (hilo separado, etc.) que causa que la condición finalmente se evalúe como verdadera. –

+0

@GeorgeDuckett disculpa por no mencionar esto. Todo esto se haría en hilos de trabajo – Odys

0

Puede comprobarlo

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

Hay que adaptar la invocación. La respuesta de @ Jon tiene invocación lambda, esta versión separa la comparand del delegado

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

Exactamente este fue mi primer intento. Más tarde me di cuenta de que podría haber varios métodos para llamar, lo que significa que tuve que declarar tantos delegados, que es algo que quiero evitar. – Odys

+1

... ¡que es exactamente lo que resuelve la versión lambda! –

Cuestiones relacionadas