2014-06-23 23 views
8

Jest jasne: na przykład wyobraź sobie przycisk w mojej formie. Kiedy użytkownik kliknie przycisk, jakaś nieważna metoda powinna zostać uruchomiona po 30 sekundach.Jak uruchomić metodę po upływie określonego czasu?

Istnieje metoda "DoAfterDelay", która wymaga dwóch wejść, pierwsza to metoda do wykonania (użycie delegatów), a druga to interwał czasowy. Więc będę miał:

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

Potrzebuję tylko kawałka kodu, aby wstrzymać proces w określonym przedziale czasu. Dotychczas używałem ten kod, aby to zrobić:

System.Threading.Thread.Sleep(Interval); 

ale ten kod nie jest dobre dla mnie, ponieważ cały proces zatrzymuje się i zamarza program. Nie chcę, aby program utknął w metodzie "DoAfterDelay". Dlatego Thread.Sleep jest bezużyteczny.

Czy ktoś mógłby zaproponować lepszy sposób? Oczywiście szukałem o tym, ale większość rozwiązań znalazłem gdzie oparte na użyciu timera (na przykład here). Ale używanie timera jest moją ostatnią opinią, ponieważ metoda powinna zostać uruchomiona raz, a użycie timerów sprawia, że ​​program jest mylący. Więc szukam lepszego rozwiązania, jeśli tak jest. A może muszę użyć timerów?

Chyba muszę grać z wątkami, ale nie jestem pewien. Zastanawiam się więc, czy ktoś mógłby mnie poprowadzić do rozwiązania. Z góry dziękuję.

+3

spróbuj użyć 'Timer'. – Adrian

Odpowiedz

7

Czy możesz użyć zadania?

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

Dzięki za odpowiedź. Zatem granie z wątkami jest rozwiązaniem. –

+2

@ MostafaFarzán To niezwykle nieefektywne/marnotrawstwo, gdy wątek siedzi w tym miejscu, nie robiąc nic, abyś mógł wykonać kod po pewnym czasie. – Servy

+0

To było w scenariuszu, gdy użytkownik klika przycisk, a więc nie ma dużego obciążenia, ponieważ nie będzie się często zdarzało. W przeciwnym razie proponuję napisanie harmonogramu zadań. –

0

DoAfterDelay uruchamia zegar, który działa tylko raz, że kiedy wygaśnie ona nazywa swój void „TheMethod'function. Dlaczego byłby brudny?

0

Oto co chcesz:

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

Jedną z zalet korzystania działania jest, że może być łatwo modyfikowany przekazać w parametrach. Powiedzmy, że chcesz móc przekazać liczbę całkowitą do DoSomethingCool. Wystarczy zmodyfikować wygląda następująco:

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

bardzo elastyczny ...

11

to gdzie można skorzystać z asynchronicznie czekają funkcjonalność .Net 4.5

Można użyć Task.Delay dać opóźnienie w milisekundach . To jest bardzo czysty sposób. np:

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

     TheMethod(); 
    } 
0

Istnieje kilka metod tworzenia wątku, ale oczywiście zależy to od tego, co robisz. Można utworzyć wątku w locie tak:

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

Ten wątek zostanie uruchomiony w tle. Funkcja, którą chcesz wykonać, powinna mieć opcję uśpienia po zakończeniu przetwarzania. Więc coś takiego:

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

Mam nadzieję, że to pomaga.

Inną opcją jest utworzenie wątku, gdy trzeba go przetworzyć i nie martwić się o opcję uśpienia. Wystarczy utworzyć nowy wątek każdym razem ładować procesowi

0

Należy utworzyć Coroutine

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

I nazywają go:

StartCoroutine(waitAndRun());