|
|
Opublikowano 12.10.2017 13:12:51
|
|
|

O klasie timerowej w C# W C# są trzy klasy timerów
1. Definiuj w System.Windows.Forms
2. Zdefiniowany w klasie System.Threading.Timer
3. Zdefiniowane w klasie System.Timers.Timer
System.Windows.Forms.Timer jest stosowany w WinForm, realizowany za pomocą mechanizmu wiadomości Windows, podobnego do sterowania Timer w VB lub Delphi, i jest realizowany wewnętrznie za pomocą API SetTimer. Główną wadą jest brak dokładnego czasu i konieczność pętli komunikatów, która nie jest dostępna dla aplikacji konsolowej.
System.Timers.Timer jest bardzo podobny do System.Threading.Timer, jest implementowany przez .NET Thread Pool, lekki, precyzyjny timing i brak specjalnych wymagań dotyczących aplikacji i komunikatów. System.Timers.Timer może być również zastosowany do WinForm, całkowicie zastępując powyższą kontrolkę Timer. Ich wadą jest brak bezpośredniego przeciągania i upuszczania i wymaganie ręcznego kodowania.
Przykład:
Użyj klasy System.Timers.Timer
System.Timers.Timer t = nowy System.Timers.Timer(10000); Instancja klasy Timer i ustaw interwał na 10 000 milisekund.
t.Elapsed += nowy System.Timers.ElapsedEventHandler(theout); Wykonaj zdarzenia, gdy nadejdzie odpowiedni czas;
t.AutoReset = prawdziwy; Ustaw czy wykonać raz (fałsz), czy cały czas (prawda);
t.Enabled = true; czy wykonać zdarzenie System.Timers.Timer.Elapsed;
public void theout (object source, System.Timers.ElapsedEventArgs e)
{
MessageBox.Show ("OK!");
}
Eksperymentalna analiza podobieństw i różnic między użyciem trzech timerów w C#
http://dotnet.chinaitlab.com/CSharp/737740.html
W C# dostępne są trzy typy timerów:
1. Standardowy timer oparty na Windows (System.Windows.Forms.Timer)
2. Timer serwerowy (System.Timers.Timer)
3. Timer wątkowania (System.Threading.Timer)
Przejdźmy przez kilka małych eksperymentów, aby przeanalizować podobieństwa i różnice między trzema timerami, zwłaszcza część dotyczącą wątków.
Zrzut ekranu z przykładem eksperymentalnym:
1. Standardowy timer oparty na Windows (System.Windows.Forms.Timer)
Pierwszą rzeczą, którą warto zauważyć, jest to, że Windows Timer jest zaprojektowany z myślą o środowiskach jednowątkowych
Ten timer jest obecny w produkcie od wersji Visual Basic 1.0 i pozostał w dużej mierze niezmieniony
Ten timer jest najprostszy w użyciu, wystarczy przeciągnąć kontrolkę Timer z toolboxa do formularza i ustawić właściwości takie jak zdarzenia i interwały
Wyniki eksperymentalne są również w pełni zgodne z charakterystyką pojedynczego wątku:
1. Po uruchomieniu tego timera identyfikator wątku potomnego będzie wyświetlany na liście identyfikatorów wątku potomnego poniżej i jest taki sam jak główny identyfikator wątku
prywatna pustka formsTimer_Tick(nadawca obiektu, EventArgs e)
{
i++;
lblSubThread.Text += "Wykonanie podwątku, identyfikator wątku:" + System.Threading.Thread.CurrentThread.ManagedThreadId.ToString() + "\r\n";
}
2. Gdy główny wątek zostanie zatrzymany na 5 sekund, wątek podrzędny zatrzymuje wykonanie, a gdy wcześniej zawieszony wątek potomny nie zostanie wykonany po 5 sekundach, następny wątek potomny zostanie wykonany bezpośrednio (czyli wygeneruje kilka linii wartości).
System.Threading.Thread.Sleep(5000);
3. Zatrzymanie zdarzeń procesu potomnego na 5 sekund spowoduje, że główne okno stanie się nieaktywne przez 5 sekund
4. Zdefiniuj zmienną statyczną wątku:
[ThreadStatic]
prywatny statyczny int i = 0;
Dodaj jeden do każdego zdarzenia podwątku, a następnie kliknij na wartość zmiennej statycznej wątku, aby uzyskać zwiększoną wartość i
2. Timer serwerowy (System.Timers.Timer)
System.Timers.Timer nie zależy od formularzy, budzi wątki z puli wątków i jest zaktualizowaną wersją tradycyjnego timera zoptymalizowaną do pracy w środowisku serwerowym
W zestawie narzędzi VS2005 nie ma gotowych sterowników i trzeba je ręcznie kodować, aby korzystać z tego timera
Są dwa sposoby jego wykorzystania,
1. Dołącz do formularza przez właściwość SynchronizingObject
System.Timers.Timers timersTimer = nowy System.Timers.Timer();
timersTimer.Enabled = false;
timersTimer.Interval = 100;
timersTimer.Elapsed += nowy System.Timers.ElapsedEventHandler(timersTimer_Elapsed);
timersTimer.SynchronizingObject = to;
W ten sposób eksperyment działa niemal tak samo jak standardowy timer Windows, z tą różnicą, że w drugim eksperymencie powyżej, choć wykonanie podwątku również zostanie wstrzymane, po 5 sekundach wszystkie wcześniej kolejkowe zadania zostaną wykonane (czyli nie brakuje kilku linii wartości).
2. Nie używaj właściwości SynchronizingObject
Ta metoda jest wielowątkowa, czyli początkowy wątek potomny i forma główna nie znajdują się w tym samym wątku. Jest jednak także problem: ponieważ podwątek jest osobnym wątkiem, kontrolki w formie nie mogą być dostępne, lecz dostępne tylko przez proxy:
delegate void SetTextCallback(string text);
Źródło: (http://blog.sina.com.cn/s/blog_5aeeb8200100bhc4.html) - (Turn) Porównanie trzech obiektów timera w C#_dash_Sina blog
。
。
void timersTimer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
{
//使用代理
string text = "wykonanie wątku potomnego, identyfikator wątku:" + System.Threading.Thread.CurrentThread.ManagedThreadId.ToString() + "\r\n";
SetTextCallback d = nowy SetTextCallback(SetText);
Dokładnie tak. Invoke(d, nowy obiekt[] { text });
i++;
}
private void SetText(string text)
{
lblSubThread.Text += tekst;
}
W ten sposób ponownie uzyskamy następujące wyniki eksperymentu:
1. Po uruchomieniu tego timera identyfikator wątku potomnego pojawi się na liście identyfikatorów wątku potomnego poniżej, różniąc się od głównego identyfikatora wątku
2. Gdy klikniesz na główny wątek, aby zatrzymać na 5 sekund, podwątek będzie kontynuowany (może nie być widoczny w interfejsie, ale łatwo go zobaczyć, wypisując plik w podwątku)
3. Zatrzymanie zdarzeń procesu potomnego na 5 sekund nie spowoduje przestania reagowania w głównym oknie
4. Za każdym razem w zdarzeniu podwątku dodaj jedną zmienną do zmiennej statycznej wątku, a następnie kliknij, czy zmienna statyczna wątku jest warta 0 czy 0 (nie zmieni zmiennej statycznej wątku w głównym oknie).
3. Timer wątkowania (System.Threading.Timer)
Timery wątkowe również nie opierają się na formularzach, są prostymi, lekkimi timerami, które wykorzystują metody callback zamiast zdarzeń i są zasilane wątkami puli wątków.
Timery wątkowe są przydatne w sytuacjach, gdy wiadomości nie są wysyłane na wątki.
Oto jak go używać:
System.Threading.Timer threadTimer;
public void ThreadMethod(Object state)
{
//使用代理
string text = "wykonanie wątku potomnego, identyfikator wątku:" + System.Threading.Thread.CurrentThread.ManagedThreadId.ToString() + "\r\n";
SetTextCallback d = nowy SetTextCallback(SetText);
Dokładnie tak. Invoke(d, nowy obiekt[] { text });
i++;
}
private void Form1_Load(object sender, EventArgs e)
{
threadTimer = nowy System.Threading.Timer(nowy System.Threading.TimerCallback(ThreadMethod), null, -1, -1);
}
Kod pauzy:
threadTimer.Change(-1, -1);
Efekt eksperymentu jest taki sam jak w przypadku drugiego sposobu serwerowego timera (System.Timers.Timer),
Oczywiście konkretne metody i zasady użycia są różne, najważniejsze jest to, że ta metoda wykorzystuje metodę agenta zamiast metody zdarzenia i może być wykonywana osobno, bez polegania na formularzach i komponentach
Poniżej znajduje się tabela podsumowana przez obcokrajowców (różnice między tymi trzema metodami):
Feature descrip{filter}tion System.Timers.Timer System.Threading.Timer System.Windows.Forms.Timer
Wsparcie dla dodawania i usuwania słuchaczy po uruchomieniu timera. Tak Nie Tak
Obsługuje odwołania w wątku interfejsu użytkownika Yes No Yes
Połączenia zwrotne z wątków uzyskanych z puli wątków Tak Tak Nie
Obsługuje przeciąganie i upuść w Windows Forms Designer Tak, Nie Tak
Odpowiednie do uruchamiania w środowisku wielowątkowym serwera Tak Tak Nie
Zawiera wsparcie dla przekazywania dowolnego stanu od inicjalizacji timera do callback. Nie, tak, nie
Implementuje IDisposable Yes
Obsługuje jednorazowe callbacki oraz okresowe powtarzające się callbacki Yes
Dostępne ponad granicami domeny aplikacji Tak, Tak, Tak
Wsparcie IComponent – dostępne w IContainer Yes No Yes |
Poprzedni:c# Rozkładanie zbioru wyrażeń Lamda, aby przyjąć wartość minimalnąNastępny:Linq: Nigdy nie używaj Count() > 0, aby określić, że zbiór jest niepusty
|