Passez un bool Foo (params []) comme méthode Argument

Il y a des fois qu'une méthode doit être exécutée plusieurs fois jusqu'à ce qu'elle soit validée. Dans mon cas, il existe des expressions comme bar.Name.Equals ("John Doe") que je veux exécuter et exécuter jusqu'à ce que cette expression valide.

Quelque chose comme:

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

TryUntillOk serait une méthode qui exécute cette expression 15 fois avec un sommeil de 100ms entre chaque appel.

J'ai lu cette excellente liste de réponses à Problèmes similaires, mais dans mon cas, il n'y a pas de délégué standar que cette méthode TryUntillOk accepterait.

Le titre de la question n'est pas constructif. N'hésitez pas à l'éditer :)

0
@GeorgeDuckett OUI. Désolé de ne pas le mentionner.
ajouté l'auteur Odys, source
Est-ce que cela fonctionnerait dans un fil séparé? Sinon, il n'y aura aucune chance que la valeur change.
ajouté l'auteur George Duckett, source

3 Réponses

Vous devez adapter l'invocation. @ La réponse de Jon a une validation lambda, cette version sépare le comparant du délégué

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
ajouté
Exactement c'était ma première tentative. Plus tard, j'ai réalisé qu'il pouvait y avoir plusieurs méthodes à appeler, ce qui signifie que j'avais dû déclarer autant de délégués, ce que je veux éviter.
ajouté l'auteur Odys, source
... c'est exactement ce que résout la version lambda!
ajouté l'auteur Eugen Rieck, source

Vous cherchez probablement quelque chose comme ceci:

bool TryRepeatedly(Func 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;
}

Ce qui serait invoqué comme suit:

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

The only interesting part here is that you specify the condition as a Func, which is a delegate to a method that takes no parameters and returns a boolean. Lambda expression syntax allows you to trivially construct such a delegate at the call site.

0
ajouté
@GeorgeDuckett désolé de ne pas mentionner cela. Tout ceci serait fait dans les fils de travail
ajouté l'auteur Odys, source
Il faut probablement noter que cela dépend de quelque chose d'extérieur (thread séparé, etc.) qui rend la condition finalement vraie.
ajouté l'auteur George Duckett, source

Tu peux le vérifier

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
}  
0
ajouté