|
|
Опубліковано 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, подібно до керування таймером у 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; Встановіть виконання один раз (хибно) чи завжди (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 розроблений для однопотокових середовищ
Цей таймер присутній у продукті з версії Visual Basic 1.0 і залишився майже без змін
Цей таймер найпростіший у використанні, просто перетягніть контроль таймера з набору інструментів у форму і встановіть властивості, такі як події та інтервали
Результати експериментів також повністю узгоджуються з характеристиками однорізьбової різьби:
1. Коли цей таймер запускається, дочірній ідентифікатор потоку відображається у списку ідентифікаторів дочірнього потоку нижче, і він збігається з основним ID потоку
private void formsTimer_Tick(object sender, EventArgs e)
{
i++;
lblSubThread.Text += "Виконання підпотоку, ідентифікатор потоку:" + System.Threading.Thread.CurrentThread.ManagedThreadId.ToString() + "\r\n";
}
2. Коли основний потік призупинено на 5 секунд, дочірній потік призупиняє виконання, а коли раніше призупинений дочірній потік не буде виконаний через 5 секунд, наступний дочірній потік виконується безпосередньо (тобто він виведе кілька рядків значень).
System.Threading.Thread.Sleep (5000);
3. Пауза подій дочірнього процесу на 5 секунд призведе до того, що головне вікно стане нечутливим на 5 секунд
4. Визначте статичну змінну потоку:
[Шум нитки]
приватний статичний 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 += новий System.Timers.ElapsedEventHandler(timersTimer_Elapsed);
timersTimer.SynchronizingObject = це;
Таким чином, експеримент працює майже так само, як стандартний таймер на базі Windows, за винятком того, що у другому експерименті вище, хоча виконання підпотоку також буде призупинено, але через 5 секунд усі раніше поставлені в чергу завдання будуть виконані (тобто кілька рядків значення не будуть відсутні).
2. Не використовуйте властивість SynchronizingObject
Цей метод багатопотоковий, тобто початковий дочірній потік і основна форма не знаходяться на одному потоці. Однак існує й проблема: оскільки підпотік є окремим потоком, керування у формі неможливо отримати доступ, а лише через проксі:
delegate void SetTextCallback (текст рядка);
Джерело: (http://blog.sina.com.cn/s/blog_5aeeb8200100bhc4.html) - (Turn) Порівняння трьох об'єктів таймера в блозі C#_dash_Sina
。
。
void timersTimer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
{
//使用代理
текст рядка = "виконання дочірнього потоку, ідентифікатор потоку:" + System.Threading.CurrentThread.ManagedThreadId.ToString() + "\r\n";
SetTextCallback d = новий SetTextCallback(SetText);
саме так. Invoke(d, новий об'єкт[] { text });
i++;
}
private void SetText (текст рядка)
{
lblSubThread.Text += текст;
}
Таким чином, ми знову отримаємо наступні результати експерименту:
1. Коли цей таймер запущено, дочірній потік ID відображається у списку ідентифікаторів дочірнього потоку нижче і відрізняється від основного ID потоку
2. Коли ви натискаєте на основний потік для паузи на 5 секунд, підпотік продовжує виконувати роботу (можливо, це не видно на інтерфейсі, але його легко побачити, вивівши файл у підпотік)
3. Пауза подій дочірнього процесу на 5 секунд не призведе до того, що головне вікно стане нереагуючим
4. Додай одну до статичної змінної потоку кожного разу під час події підпотоку, а потім натисніть, чи дорівнює статична змінна потоку 0 чи 0 (вона не змінить статичну змінну потоку у головному вікні).
3. Таймер поточності (System.Threading.Timer)
Таймери потоків також не покладаються на форми, це прості, легкі таймери, які використовують методи зворотного виклику замість подій, і працюють на потоках пулу потоків.
Таймери потоків корисні в ситуаціях, коли повідомлення не надсилаються по потоках.
Ось як його використовувати:
System.Threading.Timer threadTimer;
публічний порожній ThreadMethod(стан об'єкта)
{
//使用代理
текст рядка = "виконання дочірнього потоку, ідентифікатор потоку:" + System.Threading.CurrentThread.ManagedThreadId.ToString() + "\r\n";
SetTextCallback d = новий SetTextCallback(SetText);
саме так. Invoke(d, новий об'єкт[] { text });
i++;
}
private void Form1_Load(object sender, EventArgs e)
{
threadTimer = новий System.Threading.Timer(новий 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
Підтримка додавання та видалення слухачів після запуску таймера. Так, ні, так
Підтримує зворотні дзвінки в темі інтерфейсу користувача Yes No Yes
Зворотні дзвінки з потоків, отриманих із пулу потоків Так Так Ні
Підтримує перетягування з перетягуванням у Windows Forms Designer Так Ні Так
Підходить для роботи в серверному багатопотоковому середовищі Так Так Ні
Включає підтримку передачі довільного стану від ініціалізації таймера до зворотного виклику. Ні, так, ні
Реалізує IDisposable Так Так
Підтримує одноразові зворотні дзвінки, а також періодичні повторювані виклики Так Так
Доступно через межі домену додатків Так Так Так
Підтримує IComponent – розміщений у IContainer Так Ні Так |
Попередній:c# Дегрупування множин виразів Lamda, щоб отримати мінімальне значенняНаступний:Лінк: Ніколи не використовуйте Count() > 0, щоб визначити, що множина не є порожньою
|