web-dev-qa-db-fra.com

Comment exécuter une méthode après un intervalle de temps spécifique?

C'est clair: imaginons par exemple un bouton dans mon formulaire. Lorsqu'un utilisateur clique sur le bouton, une méthode d'annulation doit être exécutée après 30 secondes.

Il y aurait une méthode void DoAfterDelay qui prend deux paramètres d'entrée. La première est la méthode à utiliser (en utilisant des délégués) et la seconde est l'intervalle de temps. Donc j'aurai:

public delegate void IVoidDelegate();
static void DoAfterDelay(IVoidDelegate TheMethod, TimeSpan Interval)
    {
        // *** Some code that will pause the process for "Interval".
        TheMethod();
    }

Donc, j'ai juste besoin d'un morceau de code pour suspendre le processus pendant un intervalle de temps spécifique. Jusqu'à présent, j'ai utilisé ce code pour faire cela:

System.Threading.Thread.Sleep(Interval);

Mais ce code ne me convient pas, car il arrête tout le processus et gèle le programme. Je ne veux pas que le programme reste bloqué dans la méthode DoAfterDelay. C'est pourquoi le Thread.Sleep est inutile.

Alors, est-ce que quelqu'un pourrait suggérer un meilleur moyen? Bien sûr, j'ai cherché à ce sujet, mais la plupart des solutions que j'ai trouvées reposaient sur l'utilisation d'un minuteur (comme ici par exemple). Mais mon dernier avis est d’utiliser une minuterie, car la méthode ne doit être exécutée qu’une fois et que l’utilisation de minuteries rend le programme difficile à lire. Je cherche donc une meilleure solution s'il y en a. Ou peut-être que je dois utiliser des minuteries?

Je suppose que je dois jouer avec des threads, mais pas sûr. Je me demande donc si quelqu'un pourrait me guider vers une solution. Merci d'avance.

13
Mostafa Farzán

Pouvez-vous utiliser une tâche?

    Task.Factory.StartNew(() =>
    {
        System.Threading.Thread.Sleep(Interval);
        TheMethod();
    });
10
Bartosz Wójtowicz

C’est là que vous pouvez utiliser la fonctionnalité d’attente asynchrone de .Net 4.5

Vous pouvez utiliser Task.Delay et donner le délai en millisecondes ..__ C'est une façon très propre. ex:

    private async void button1_Click(object sender, EventArgs e)
    {
        await Task.Delay(5000);

        TheMethod();
    }
13
Jimmy Hannon

Vous devriez créer une Coroutine 

public IEnumerator waitAndRun()
{
    // WAIT FOR 3 SEC
    yield return new WaitForSeconds(3);
    // RUN YOUR CODE HERE ...
}

Et appelez-le avec:

StartCoroutine(waitAndRun());
0
David

Vous pouvez spécifier les secondes exactes en utilisant

DateTime runTime = new DateTime();
double waitSeconds = (runTime - DateTime.Now).TotalSeconds;

Task.Factory.StartNew(() =>
{
    Thread.Sleep(TimeSpan.FromSeconds(waitSeconds));
    YourMethod();
});

runTime => Quand vous voulez exécuter la méthode.

0
Amey Vartak

Voici ce que vous voulez:

    public static void Example1c()
    {
        Action action = DoSomethingCool;
        TimeSpan span = new TimeSpan(0, 0, 0, 5);

        ThreadStart start = delegate { RunAfterTimespan(action, span); };
        Thread t4 = new Thread(start);
        t4.Start();

        MessageBox.Show("Thread has been launched");
    }
    public static void RunAfterTimespan(Action action, TimeSpan span)
    {
        Thread.Sleep(span);
        action();
    }
    private static void DoSomethingCool()
    {
        MessageBox.Show("I'm doing something cool");
    }

L'un des avantages de l'utilisation de Action est qu'il peut être facilement modifié pour passer des paramètres. Supposons que vous souhaitiez pouvoir passer un entier à DoSomethingCool. Il suffit de modifier ainsi:

    public static void Example1c()
    {
        Action<int> action = DoSomethingCool;
        TimeSpan span = new TimeSpan(0, 0, 0, 5);
        int number = 10;

        ThreadStart start = delegate { RunAfterTimespan(action, span, number); };
        Thread t4 = new Thread(start);
        t4.Start();

        MessageBox.Show("Thread has been launched");
    }
    public static void RunAfterTimespan(Action<int> action, TimeSpan span, int number)
    {
        Thread.Sleep(span);
        action(number);
    }
    private static void DoSomethingCool(int number)
    {
        MessageBox.Show("I'm doing something cool");
    }

Très souple...

Il existe plusieurs méthodes de création de thread, mais bien sûr, cela dépend de ce que vous faites. Vous pouvez créer un thread à la volée comme ceci:

Thread aNewThread = new Thread(
    () => OnGoingFunction()
);
aNewThread.Start();

Ce fil sera exécuté en arrière-plan. La fonction que vous souhaitez effectuer doit avoir une méthode de veille pour dormir lorsque son traitement est terminé. Donc, quelque chose comme ça:

private void OnGoingFunction()
{
   //Code....
   Thread.Sleep(100); //100 ms, this is in the thead so it will not stop your winForm
   //More code....
}

J'espère que ça aide.

Une autre option consiste à créer le fil à chaque fois que vous avez besoin de le traiter sans vous soucier de l'option de veille. Il suffit de créer un nouveau thread à chaque fois pour charger le processus

0
sunnysidedown916

DoAfterDelay démarre une minuterie qui ne s'exécute qu'une fois et qui, lorsqu'elle arrive à expiration, appelle votre fonction 'TheMethod' vide .. Pourquoi cela serait-il désordonné?

0
Bluemoon10