Эта статья является зеркальной статьёй машинного перевода, пожалуйста, нажмите здесь, чтобы перейти к оригиналу.

Вид: 19523|Ответ: 1

[Источник] Реализация трёх таймеров в C#

[Скопировать ссылку]
Опубликовано 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, полностью заменяя вышеуказанное управление таймером. Их недостаток в том, что они не поддерживают прямое перетаскивание и требуют ручного кодирования.



Пример:

Используйте класс 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 предназначен для однопоточных сред



Этот таймер присутствует в продукте с версии Visual Basic 1.0 и остался практически без изменений



Этот таймер самый простой в использовании, просто перетащите управление таймером из инструментария в форму и задайте такие свойства, как события и интервалы



Экспериментальные результаты также полностью соответствуют характеристикам однопоточной резьбы:



1. При запуске этого таймера идентификатор дочернего потока отображается в списке идентификаторов дочерних потоков ниже, и он совпадает с основным идентификатором потока



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;



таймерыTimer.Interval = 100;



timersTimer.Elapsed += new System.Timers.ElapsedEventHandler(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)



{



//使用代理



текст строки = "исполнение дочернего потока, идентификатор потока:" + 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 дочернего потока отображается в списке идентификаторов дочерних потоков ниже и отличается от основного идентификатора потока







2. Когда вы кликаете на основной поток для паузы на 5 секунд, подпоток продолжит выполнение (он может быть не виден на интерфейсе, но легко увидеть, выведя файл в подпотоке)



3. Пауза событий дочернего процесса на 5 секунд не приведёт к тому, что главное окно станет неотзывчивым



4. Добавляйте одну в статическую переменную потока каждый раз в событии подпотока, а затем нажмите, стоит ли статическая переменная потока 0 или 0 (она не изменит статическую переменную потока в главном окне).



3. Таймер потоков (System.Threading.Timer)



Таймеры потоков также не зависят от форм, это простые, лёгкие таймеры, использующие методы обратного вызова вместо событий, и работают на потоках пула потоков.



Таймеры потоков полезны в ситуациях, когда сообщения не отправляются по потокам.



Вот как им пользоваться:



System.Threading.Timer threadTimer;



public void ThreadMethod(состояние объекта)



{



//使用代理



текст строки = "исполнение дочернего потока, идентификатор потока:" + 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



Поддержка добавления и удаления слушателей после запуска таймера. Да, нет, да.



Поддерживает обратные вызовы в теме пользовательского интерфейса Yes No Yes



Обратные звонки из потоков, полученных из пула потоков. Да, да, нет.



Поддерживает перетаскивание в Windows Forms Designer Yes Нет Да



Подходит для работы в серверной многопоточной среде Да Да Нет



Включает поддержку передачи произвольного состояния от инициализации таймера к обратному вызову. Нет, да, нет



Реализует IDisposable Да



Поддерживает одноразовые обратные звонки, а также периодические повторяющиеся вызовы Да Да



Доступно через границы доменов приложений Да Да Да



Поддерживает IComponent — можно разместить в IContainer Да Нет Да




Предыдущий:c# Дегруппировка выражений Lamda, чтобы принять минимальное значение
Следующий:Linq: Никогда не используйте Count() > 0, чтобы определить, что множество не пусто
Опубликовано 08.11.2017 14:02:44 |
Это правда. Это действительно хорошо, но почему ты не ответил на пост?
Отказ:
Всё программное обеспечение, программные материалы или статьи, публикуемые Code Farmer Network, предназначены исключительно для учебных и исследовательских целей; Вышеуказанный контент не должен использоваться в коммерческих или незаконных целях, иначе пользователи несут все последствия. Информация на этом сайте взята из Интернета, и споры по авторским правам не имеют отношения к этому сайту. Вы должны полностью удалить вышеуказанный контент с компьютера в течение 24 часов после загрузки. Если вам нравится программа, пожалуйста, поддержите подлинное программное обеспечение, купите регистрацию и получите лучшие подлинные услуги. Если есть нарушение, пожалуйста, свяжитесь с нами по электронной почте.

Mail To:help@itsvse.com