2014-06-23 7 views
8

È chiaro: ad esempio, immagina un pulsante nel mio modulo. Quando l'utente fa clic sul pulsante, alcuni metodi void dovrebbero essere eseguiti dopo 30 secondi.Come eseguire un metodo dopo un intervallo di tempo specifico?

Ci sarebbe un metodo di annullamento "DoAfterDelay" che richiede 2 input, il primo è il metodo da eseguire (utilizzando i delegati) e l'altro è l'intervallo di tempo. Così avrò:

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

Così ho solo bisogno di un pezzo di codice per mettere in pausa il processo per un intervallo di tempo specifico. Prima d'ora, ho usato questo codice per farlo:

System.Threading.Thread.Sleep(Interval); 

Ma questo codice non va bene per me, perché si ferma tutto il processo e si blocca il programma. Non voglio che il programma rimanga bloccato nel metodo "DoAfterDelay". Ecco perché il Thread.Sleep è inutile.

Quindi qualcuno potrebbe suggerire un modo migliore? Ovviamente l'ho cercato, ma la maggior parte delle soluzioni che ho trovato erano basate su un timer (ad esempio here). Ma usare il timer è la mia ultima opinione, perché il metodo dovrebbe essere eseguito una sola volta e l'uso dei timer rende il programma confuso da leggere. Quindi sto cercando una soluzione migliore se c'è. O forse devo usare i timer?

Credo di dover giocare con i thread, ma non sono sicuro. Quindi mi chiedo se qualcuno potrebbe guidarmi verso una soluzione. Grazie in anticipo.

+3

provare a utilizzare un 'Timer'. – Adrian

risposta

7

È possibile utilizzare un'attività?

Task.Factory.StartNew(() => 
    { 
     System.Threading.Thread.Sleep(Interval); 
     TheMethod(); 
    }); 
+0

Grazie per la risposta. Quindi giocare con i thread è la soluzione. –

+2

@ MostafaFarzán È estremamente inefficiente/dispendioso avere un thread seduto lì senza fare nulla, in modo da poter eseguire del codice dopo un certo periodo di tempo. – Servy

+0

Era in uno scenario in cui un utente fa clic su un pulsante, quindi non un grande sovraccarico in quanto non accadrà frequentemente. Altrimenti suggerirei di scrivere un task scheduler. –

0

DoAfterDelay avvia un timer che appena viene eseguito una volta, che quando scade chiama tua TheMethod'function vuoto'. Perché questo sarebbe disordinato?

0

Ecco ciò che si vuole:

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

Uno dei vantaggi dell'utilizzo di azione è che può essere facilmente modificato per passare parametri. Supponiamo che tu voglia essere in grado di passare un intero a DoSomethingCool. Basta modificare questa convenzione:

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

Molto flessibile ...

11

Questo è dove è possibile utilizzare l'asincrona attendono funzionalità di .Net 4.5

È possibile utilizzare un Task.Delay dare il ritardo in millisecondi . Questo è un modo molto pulito. es:

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

     TheMethod(); 
    } 
0

Ci sono diversi metodi di creazione di thread, ma, naturalmente, dipende da quello che stai facendo. È possibile creare un filo al volo come questo:

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

Questo thread sarà in esecuzione in background. La funzione che si desidera eseguire dovrebbe avere un metodo di sospensione per dormire quando viene eseguita l'elaborazione. Quindi qualcosa del genere:

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

Spero che questo aiuti.

Un'altra opzione è creare il thread ogni volta che è necessario elaborarlo e non preoccuparsi dell'opzione di sospensione. Basta creare un nuovo thread ogni volta per caricare il processo di

0

È necessario creare un Coroutine

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

e chiamarlo con:

StartCoroutine(waitAndRun());