System.Timers.Timer против System.Threading.Timer
В последнее время я проверял некоторые из возможных таймеров, и Threading.Timer и Timers.Timer - те, которые мне нужны (так как они поддерживают пул потоков).
Я делаю игру, и я планирую использовать все типы событий, с разными интервалами и т. Д.
Что будет лучшим?
9 ответов
Эта статья предлагает довольно полное объяснение:
" Сравнение классов таймеров в библиотеке классов.NET Framework" - также доступно в виде файла.chm
Конкретная разница заключается в том, что System.Timers.Timer
ориентирован на многопоточные приложения и поэтому является потокобезопасным благодаря SynchronizationObject
собственность, тогда как System.Threading.Timer
по иронии судьбы не является потокобезопасным из коробки.
Я не верю, что между этими двумя понятиями есть разница, поскольку они касаются того, насколько малы могут быть ваши интервалы.
System.Threading.Timer
простой таймер. Он вызывает вас обратно в поток пула потоков (из рабочего пула).
System.Timers.Timer
это System.ComponentModel.Component
это оборачивает System.Threading.Timer
и предоставляет некоторые дополнительные функции, используемые для диспетчеризации в определенном потоке.
System.Windows.Forms.Timer
вместо этого оборачивает собственный HWND только для сообщений и использует оконные таймеры для вызова событий в этом цикле сообщений HWND.
Если ваше приложение не имеет пользовательского интерфейса и вам нужен максимально легкий и универсальный таймер.Net, возможный (потому что вы счастливы, выясняя свою собственную многопоточность / диспетчеризацию), тогда System.Threading.Timer
так хорошо, как он получает в рамках.
Я не до конца понимаю, с чем предполагаемые проблемы с безопасностью потоков System.Threading.Timer
являются. Возможно, это то же самое, что задано в этом вопросе: потокобезопасность System.Timers.Timer против System.Threading.Timer, или, возможно, каждый просто означает, что:
Легко писать условия гонки, когда вы используете таймеры. Например, смотрите этот вопрос: Таймер (System.Threading) поток безопасности
повторный вход уведомлений таймера, когда ваше событие таймера может вызвать и перезвонить вам во второй раз, прежде чем вы закончите обработку первого события. Например, посмотрите на этот вопрос: Потоковое выполнение с использованием System.Threading.Timer и Monitor
В своей книге "CLR Via C#" Джефф Ритчер не рекомендует использовать System.Timers.Timer
этот таймер получен из System.ComponentModel.Component
, что позволяет использовать его в области проектирования Visual Studio. Так что это было бы полезно, только если вы хотите, чтобы таймер на поверхности дизайна.
Он предпочитает использовать System.Threading.Timer
для фоновых задач в потоке пула потоков.
Информация от Microsoft об этом (см. Замечания по MSDN):
- System.Timers.Timer, который запускает событие и выполняет код в одном или нескольких приемниках событий через равные промежутки времени. Класс предназначен для использования в качестве серверного или сервисного компонента в многопоточной среде; он не имеет пользовательского интерфейса и не виден во время выполнения.
- System.Threading.Timer, который регулярно выполняет один метод обратного вызова в потоке пула потоков. Метод обратного вызова определяется, когда создается таймер, и его нельзя изменить. Как и класс System.Timers.Timer, этот класс предназначен для использования в качестве серверного или служебного компонента в многопоточной среде; он не имеет пользовательского интерфейса и не виден во время выполнения.
- System.Windows.Forms.Timer (только.NET Framework), компонент Windows Forms, который запускает событие и выполняет код в одном или нескольких приемниках событий через равные промежутки времени. Компонент не имеет пользовательского интерфейса и предназначен для использования в однопоточной среде; он выполняется в потоке пользовательского интерфейса.
- System.Web.UI.Timer (только.NET Framework), компонент ASP.NET, который выполняет асинхронную или синхронную обратную передачу веб-страниц с регулярным интервалом.
Интересно отметить, что System.Timers.Timer
устарел в.NET Core 1.0, но был снова реализован в.NET Core 2.0 (/ .NET Standard 2.0). Цель.NET Standard 2.0 состояла в том, чтобы было как можно проще переключиться с.NET Framework, что, вероятно, стало причиной его возвращения.
Когда он устарел, рекомендуется использовать надстройку анализатора переносимости.NET Visual Studio System.Threading.Timer
вместо.
Похоже, что Microsoft одобряет System.Threading.Timer
до System.Timers.Timer
,
РЕДАКТИРОВАТЬ ПРИМЕЧАНИЕ 2018-11-15: я передаю свой ответ, так как старая информация о.NET Core 1.0 больше не действительна.
Одно важное отличие, не упомянутое выше, которое может вас поймать, заключается в том, что System.Timers.Timer
молча глотает исключения, тогда как System.Threading.Timer
не делает.
Например:
var timer = new System.Timers.Timer { AutoReset = false };
timer.Elapsed += (sender, args) =>
{
var z = 0;
var i = 1 / z;
};
timer.Start();
против
var timer = new System.Threading.Timer(x =>
{
var z = 0;
var i = 1 / z;
}, null, 0, Timeout.Infinite);
Я нашел краткое сравнение с MSDN
Библиотека классов.NET Framework включает четыре класса с именем Timer, каждый из которых предлагает различные функции:
System.Timers.Timer
, который запускает событие и выполняет код в одном или нескольких приемниках событий через равные промежутки времени. Класс предназначен для использования в качестве серверного или сервисного компонента в многопоточной среде; он не имеет пользовательского интерфейса и не виден во время выполнения.
System.Threading.Timer
, который выполняет один метод обратного вызова в потоке пула потоков через равные промежутки времени. Метод обратного вызова определяется, когда создается таймер, и его нельзя изменить. Как и класс System.Timers.Timer, этот класс предназначен для использования в качестве серверного или служебного компонента в многопоточной среде; он не имеет пользовательского интерфейса и не виден во время выполнения.
System.Windows.Forms.Timer
компонент Windows Forms, который запускает событие и выполняет код в одном или нескольких приемниках событий через равные промежутки времени. Компонент не имеет пользовательского интерфейса и предназначен для использования в однопоточной среде.
System.Web.UI.Timer
компонент ASP.NET, который выполняет асинхронную или синхронную обратную передачу веб-страниц с регулярным интервалом.
Из MSDN: System.Threading.Timer
это простой, легкий таймер, который использует методы обратного вызова и обслуживается потоками пула потоков. Это не рекомендуется для использования с Windows Forms, потому что его обратные вызовы не происходят в потоке пользовательского интерфейса. System.Windows.Forms.Timer
это лучший выбор для использования с Windows Forms. Для серверной функциональности таймера, вы можете рассмотреть возможность использования System.Timers.Timer
, который вызывает события и имеет дополнительные функции.
Как уже упоминалось в ссылке на MS Docs, одно из основных различий между и заключается в том, что выполняется один метод обратного вызова, определенный один раз , когда он реагирует на события, поэтому поддерживает несколько подписчиков, которых также можно удалить.
Как также упоминалось выше,
System.Timers.Timer
использует
System.Threading.Timer
внутренне, например, Enable=false размещает внутренний таймер и повторно создает его на Enable=true/Start(): https://source.dot.net/#System.ComponentModel.TypeConverter/System/Timers/Timer.cs
Два класса функционально эквивалентны, за исключением того, что System.Timers.Timer
имеет возможность вызывать все свои обратные вызовы истечения таймера через ISynchronizeInvoke, устанавливая SynchronizingObject. В противном случае оба таймера вызывают обратные вызовы с истечением срока действия в потоках пула потоков.
Когда вы перетаскиваете System.Timers.Timer
на поверхности разработки Windows Forms Visual Studio устанавливает SynchronizingObject для объекта формы, что приводит к вызову всех обратных вызовов с истечением срока действия в потоке пользовательского интерфейса.