Jak dodać opóźnienie o 2 lub 3 sekundy [zamknięte]

133

Jak mogę dodać opóźnienie do programu w C #?

Mulder
źródło
2
Jest na to kilka sposobów, ale dlaczego musisz dodać opóźnienie? Gdybyśmy wiedzieli, bylibyśmy w stanie zaproponować najbardziej odpowiedni sposób, aby to zrobić.
ChrisF
3
To pytanie jest beznadziejnie niedokumentowane, aby kiedykolwiek polecać Thread.Sleep ().
Hans Passant
1
Dla wyjaśnienia głosowałem za zamknięciem tego pytania, ponieważ nie podałeś wystarczająco dużo szczegółów, aby ktokolwiek mógł udzielić dobrej, dobrej odpowiedzi. Jestem całkowicie skłonny ponownie otworzyć to pytanie jako ważne pytanie, jeśli dodasz więcej szczegółów na temat tego, co dokładnie próbujesz zrobić. Głosowanie za wcześniejszym zamknięciem jest sposobem zapobiegania zalewowi „szumowych” odpowiedzi na pytania niskiej jakości. Gdy dodasz więcej szczegółów, zostaw komentarz i / lub oflaguj mod, aby ponownie go otworzyć.
Cody Grey
16
Zła decyzja o zamknięciu tego pytania. To jest pytanie i nie ma nic złego w tym, aby miało charakter ogólny. Zrozumiałem to doskonale.
user2430797
5
Kolejne pytanie, którego szukałem, na które odpowiadało pytanie, które zostało zamknięte bez powodu.
Glenn Maynard

Odpowiedzi:

185

Możesz użyć Thread.Sleep()funkcji, np

int milliseconds = 2000;
Thread.Sleep(milliseconds);

co całkowicie zatrzymuje wykonywanie bieżącego wątku na 2 sekundy.

Prawdopodobnie najbardziej odpowiednim scenariuszem Thread.Sleepjest to, gdy chcesz opóźnić operacje w innym wątku, innym niż główny, np .:

 MAIN THREAD        --------------------------------------------------------->
 (UI, CONSOLE ETC.)      |                                      |
                         |                                      |
 OTHER THREAD            ----- ADD A DELAY (Thread.Sleep) ------>

W przypadku innych scenariuszy (np. Rozpoczęcie operacji po pewnym czasie itp.) Sprawdź odpowiedź Cody'ego .

digEmAll
źródło
13
Unikaj używania Thead.Sleep przyczyna Całkowicie zablokuje bieżący wątek przed zrobieniem CZEGOKOLWIEK do zakończenia czasu trwania.
Mohammed Swillam,
7
@Mohammed: tak, oczywiście całkowicie zablokuje bieżnik. Ale czasami może się przydać ... to naprawdę zależy od potrzeb OP ...
digEmAll
13
Ponieważ nie mogę opublikować nowej odpowiedzi, chciałbym skomentować - jeśli nie chcesz, aby blokował program, możesz użyć await Task.Delay(milliseconds). To zadziałało dla mnie :)
SaiyanGirl
W moim przypadku nie mogłem użyć await, ponieważ zostałem wezwany z części programu napisanej przez kogoś innego. To nie jest oczekiwane, ale jeśli się „zawieszę”, mogę pracować przez 10 sekund, zanim moje pliki zostaną zamknięte. Spanie 2 sekundy działa jak marzenie;) Więc w niektórych przypadkach tak właśnie jest.
ecth
@MohammedElSayed: Odpowiedź zależy. Wszystko zależy od intencji użytkowania. W moim przypadku muszę przespać wątek dokładnie na 0,6 sekundy, aby uniknąć ograniczenia indeksu podczas wstawiania do bazy danych.
GunWanderer
66

Używaj minutnika z interwałem ustawionym na 2–3 sekundy.

Masz do wyboru trzy różne opcje, w zależności od typu aplikacji, którą piszesz:

  1. System.Timers.Timer
  2. System.Windows.Forms.Timer
  3. System.Threading.Timer

Nie używaj, Thread.Sleepjeśli aplikacja musi przetwarzać dane wejściowe w tym wątku w tym samym czasie (WinForms, WPF), ponieważ Sleepcałkowicie zablokuje wątek i uniemożliwi przetwarzanie innych komunikatów. Zakładając, że jest to aplikacja jednowątkowa (jak większość), cała aplikacja przestanie odpowiadać, a nie tylko opóźni operację, jak prawdopodobnie zamierzałeś. Zauważ, że używanie trybu uśpienia w czystej aplikacji konsolowej może być w porządku, ponieważ nie ma "zdarzeń" do obsłużenia lub w oddzielnym wątku (Task.Delay jest lepsza opcja).

Oprócz timerów i Sleepmożesz użyć Task.Delaywersji asynchronicznej Sleep, która nie blokuje wątku przed przetwarzaniem zdarzeń (jeśli jest używany prawidłowo - nie zamieniaj go w nieskończony sen z .Wait()).

 public async void ClickHandler(...)
 {
      // whatever you need to do before delay goes here         

      await Task.Delay(2000);

      // whatever you need to do after delay.
 }

To samo await Task.Delay(2000)można wykorzystać w Mainmetodzie aplikacji konsolowej, jeśli używasz języka C # 7.1 ( główny Async na blogach MSDN ).

Uwaga: opóźnianie operacji Sleepma tę zaletę, że pozwala uniknąć sytuacji wyścigu, które wynikają z potencjalnego uruchomienia wielu operacji z licznikami / Delay. Niestety zamrażanie aplikacji opartej na interfejsie użytkownika jest nie do przyjęcia, więc musisz pomyśleć o tym, co się stanie, jeśli uruchomisz wiele opóźnień (tj. Jeśli zostanie wywołane kliknięciem przycisku) - rozważ wyłączenie takiego przycisku, anulowanie timera / zadania lub upewnienie się, że jest opóźnione operację można bezpiecznie wykonać wiele razy.

Cody Gray
źródło
5
Jeśli jest to aplikacja konsolowa, plik Thread.Sleep ostrzeżenie może nie być tak ważne.
Merlyn Morgan-Graham
1
Istnieje czwarty zegar: System.Web.UI.Timer , składnik ASP.NET, który wykonuje asynchroniczne lub synchroniczne ogłaszanie zwrotne stron internetowych w regularnych odstępach czasu.
David
1
Powinna być najlepsza odpowiedź. Gdyby miał przykład użycia jednego z timerów, dostałby więcej głosów ...
Mercutio
Cody Gray, czy możesz dodać await Task.Delay()wersję i komentarz w tekście, którego aplikacja konsolowa prawdopodobnie będzie chciała używać Sleep(nie-asynchroniczna Main) lub Delay(asynchroniczna Main)
Alexei Levenkov,
1
@CodyGray gotowe.
Alexei Levenkov
39

Przez 2,3 sekundy powinieneś:

System.Threading.Thread.Sleep(2300);
Mitja Bonca
źródło
6
System.Threading.Thread.Sleep(
    (int)System.TimeSpan.FromSeconds(3).TotalMilliseconds);

Lub z usingoświadczeniami:

Thread.Sleep((int)TimeSpan.FromSeconds(2).TotalMilliseconds);

Wolę to 1000 * numSeconds(lub po prostu 3000), ponieważ dzięki temu jest bardziej oczywiste, co dzieje się z kimś, kto wcześniej nie używał Thread.Sleep. Lepiej dokumentuje twoje zamiary.

Merlyn Morgan-Graham
źródło
2
+1 dla TimeSpan powyżej 1000 *
Lefty
Z .NET 4 i nowszymi wersjami można używać Thread.Sleep(TimeSpan)bezpośrednio, bez konieczności rzutowania na int.
Holf