|
|
Публикувано в 12.10.2017 г. 13:12:51 ч.
|
|
|

За класа таймер в C# Има три таймер класа в C#
1. Дефиниране в System.Windows.Forms
2. Дефинирано в класа System.Threading.Timer
3. Дефинирано в класа System.Timers.Timer
System.Windows.Forms.Timer се прилага към WinForm, реализиран чрез механизма за съобщения в Windows, подобно на контрола Timer във VB или Delphi, и се реализира вътрешно чрез API SetTimer. Основният му недостатък е, че времето не е прецизно и трябва да има цикъл на съобщения, който не е достъпен за конзолното приложение.
System.Timers.Timer е много подобен на System.Threading.Timer, те се реализират чрез .NET Thread Pool, лек, точен тайминг и без специални изисквания за приложения и съобщения. System.Timers.Timer може да се приложи и към WinForm, напълно заменяйки горния контрол Timer. Недостатъкът им е, че не поддържат директно плъзгане и пускане и изискват ръчно кодиране.
Пример:
Използвайте класа System.Timers.Timer
System.Timers.Timer t = нов System.Timers.Timer(10000); Инстанцирай класа Таймер и настрой интервала на 10 000 милисекунди.
t.Elapsed += нов System.Timers.ElapsedEventHandler (theout); Изпълняване на събития, когато настъпи времето;
t.AutoReset = true; Задайте дали да се изпълнява веднъж (false) или винаги (true);
t.Enabled = true; дали да се изпълни събитието System.Timers.Timer.Elapsed;
public void theout(object source, System.Timers.ElapsedEventArgs e)
{
MessageBox.Show("Добре!");
}
Експериментален анализ на приликите и разликите между използването на три таймера в C#
http://dotnet.chinaitlab.com/CSharp/737740.html
В C# са налични три типа таймери:
1. Стандартен таймер за Windows (System.Windows.Forms.Timer)
2. Сървърен таймер (System.Timers.Timer)
3. Таймер за нишки (System.Threading.Timer)
Нека разгледаме някои малки експерименти, за да анализираме приликите и разликите между трите таймера, особено частта, свързана с нишките.
Скрийншот на експериментален пример:
1. Стандартен таймер за Windows (System.Windows.Forms.Timer)
Първото нещо, което трябва да се отбележи, е, че Windows Timer е предназначен за еднонишкови среди
Този таймер присъства в продукта още от версия 1.0 на Visual Basic и остава почти непроменен
Този таймер е най-лесен за използване – просто плъзнете контрола на таймера от кутията с инструменти във формата и задайте свойствата като събития и интервали
Експерименталните резултати също са напълно съвместими с характеристиките на единичната нишка:
1. Когато този таймер се стартира, ID на дъщерната нишка ще се покаже в списъка с идентификатори на дъщерна нишка по-долу и е същият като основния ID на нишката
private void formsTimer_Tick(object sender, EventArgs e)
{
i++;
lblSubThread.Text += "Изпълнение на поднишка, ID на нишка:" + System.Threading.Thread.CurrentThread.ManagedThreadId.ToString() + "\r\n";
}
2. Когато основната нишка бъде пауза за 5 секунди, дъщерната нишка ще паузира изпълнението, а когато предварително спряната дъщерна нишка не се изпълни след 5 секунди, следващата дъщерна нишка се изпълнява директно (т.е. ще изведе няколко реда стойности).
System.Threading.Thread.Sleep (5000);
3. Пауза на събитията от дъщерен процес за 5 секунди ще доведе до неотзивчивостта на основния прозорец за 5 секунди
4. Дефинирайте статична променлива на нишката:
[Шум от нишка]
Private static int i = 0;
Добави по една към всяко събитие от поднишката и след това кликни върху стойността на статичната променлива на нишката, за да получиш увеличената i стойност
2. Сървърен таймер (System.Timers.Timer)
System.Timers.Timer не зависи от форми, пробужда нишки от пула на нишки и е обновена версия на традиционния таймер, оптимизирана да работи в сървърна среда
В комплекта с инструменти на VS2005 няма готови контроли и трябва да се кодират ръчно, за да се използва този таймер
Има два начина да го използваш,
1. Прикачете се към формата чрез свойството SynchronizingObject
System.Timers.Timer timersTimer = нов System.Timers.Timer();
timersTimer.Enabled = false;
timersTimer.Interval = 100;
timersTimer.Elapsed += new System.Timers.ElapsedEventHandleler(timersTimer_Elapsed);
timersTimer.SynchronizingObject = това;
По този начин експериментът работи почти по същия начин като стандартен таймер за Windows, с изключение на това, че във втория експеримент по-горе, въпреки че изпълнението на поднишката също ще бъде паузано, но след 5 секунди всички предварително поставени задачи ще бъдат изпълнени (т.е. няма да липсват няколко реда стойност).
2. Не използвайте свойството SynchronizingObject
Този метод е многопоточн, тоест началната дъщерна нишка и основната форма не са на една и съща нишка. Въпреки това има и проблем: тъй като поднишката е отделна нишка, контролите във формата не могат да бъдат достъпени, а могат да бъдат достъпени само чрез прокси:
delegate void SetTextCallback (текст на низ);
Източник: (http://blog.sina.com.cn/s/blog_5aeeb8200100bhc4.html) - (Завъртане) Сравнение на три таймерни обекта в блога C#_dash_Sina
。
。
void timersTimer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
{
//使用代理
низов текст = "изпълнение на дъщерна нишка, ID на нишка:" + System.Threading.Thread.CurrentThread.ManagedThreadId.ToString() + "\r\n";
SetTextCallback d = нов SetTextCallback(SetText);
това. Invoke(d, new object[] { text });
i++;
}
private void SetText (текст на низове)
{
lblSubThread.Text += текст;
}
По този начин ще получим отново следните резултати от експеримента:
1. Когато този таймер се стартира, ID-то на дъщерната нишка ще се покаже в списъка с идентификатори на дъщерна нишка по-долу и е различно от основния ID на нишка
2. Когато кликнете върху основната нишка, за да паузирате за 5 секунди, поднишката ще продължи да се изпълнява (може да не е видима на интерфейса, но лесно се вижда, като излезе файлът в поднишката)
3. Пауза на събитията от детски процес за 5 секунди няма да причини основния прозорец да стане неотзивчив
4. Добавете една към статичната променлива на нишката всеки път в събитието на поднишката, след което кликнете дали статичната променлива на нишката струва 0 или 0 (тя няма да промени статичната променлива в основния прозорец).
3. Таймер за нишки (System.Threading.Timer)
Таймерите на нишки също не разчитат на форми, те са прости, леки таймери, които използват callback методи вместо събития, и се захранват от thread pool нишки.
Таймерите за нишки са полезни в ситуации, когато съобщенията не се изпращат по нишките.
Ето как да го използвате:
System.Threading.Timer threadTimer;
public void ThreadMethod(Object state)
{
//使用代理
низов текст = "изпълнение на дъщерна нишка, ID на нишка:" + System.Threading.Thread.CurrentThread.ManagedThreadId.ToString() + "\r\n";
SetTextCallback d = нов SetTextCallback(SetText);
това. Invoke(d, new object[] { text });
i++;
}
private void Form1_Load(object sender, EventArgs e)
{
threadTimer = нов System.Threading.Timer(new System.Threading.TimerCallback(ThreadMethod), null, -1, -1);
}
Код за пауза:
threadTimer.Change(-1, -1);
Ефектът от експеримента е същият като при втория начин на сървърния таймер (System.Timers.Timer),
Разбира се, специфичните методи и принципи на използване са различни, най-важното е, че този метод използва агентния метод вместо събитийния метод и може да се изпълнява отделно, без да се разчита на форми и компоненти
Следва таблица, обобщена от чужденци (разликата между трите метода):
Feature descrip{filter}tion System.Timers.Timer System.Threading.Timer System.Windows.Forms.Timer
Поддръжка за добавяне и премахване на слушатели след стартиране на таймера. Да, не, да.
Поддържа обратни позиви в темата за потребителския интерфейс Да Не Да
Обаждания обратно от теми, получени от пула на нишки. Да, да, не.
Поддържа плъзгане и пускане в Windows Forms Designer Да Не Да
Подходящ за работа в сървърна многопоточна среда Да Да Не
Включва поддръжка за предаване на произволно състояние от инициализацията на таймера към обратното повикване. Не, да, не.
Имплементира IDisposable Да Да Да
Поддържа еднократни обратни повиквания, както и периодични повтарящи се обаждания Да Да
Достъпно през границите на домейна на приложението Да Да Да
Поддържа IComponent – хоства се в IContainer Да Не Да |
Предишен:c# Дегрупиране на множествата от изрази в Lamda, за да вземе минималната стойностСледващ:Linq: Никога не използвайте Count() > 0, за да определите, че множеството не е празно
|