Одно отличие состоит в том, что System.Threading.Timer
отправляет обратный вызов в потоке пула потоков, а не каждый раз создает новый поток. Если вам нужно, чтобы это происходило более одного раза в течение срока службы вашего приложения, это сэкономит накладные расходы на создание и уничтожение группы потоков (процесс, который очень ресурсоемкий, как указано в статье, на которую вы ссылаетесь), поскольку просто повторно используйте потоки в пуле, и если у вас будет более одного таймера, работающего одновременно, это означает, что у вас будет меньше потоков, работающих одновременно (также экономя значительные ресурсы).
Другими словами, Timer
будет гораздо более эффективным. Это также может быть более точным, так как Thread.Sleep
гарантированно будет ожидать по крайней мере столько времени, сколько вы укажете (ОС может перевести его в спящий режим гораздо дольше). Конечно, Timer
все еще не будет точно точным, но цель состоит в том, чтобы вызвать обратный вызов как можно ближе к указанному времени, в то время как это НЕ обязательно намерение Thread.Sleep
.
Что касается уничтожения Timer
, обратный вызов может принять параметр, поэтому вы можете передать сам Timer
в качестве параметра и вызвать Dispose в обратном вызове (хотя я не пробовал это - я возможно, таймер может быть заблокирован во время обратного вызова).
Редактировать: Нет, я полагаю, вы не можете этого сделать, поскольку вам нужно указать параметр обратного вызова в самом конструкторе Timer
.
Может быть, что-то вроде этого? (Опять же, на самом деле не пробовал)
class TimerState
{
public Timer Timer;
}
... и для запуска таймера:
TimerState state = new TimerState();
lock (state)
{
state.Timer = new Timer((callbackState) => {
action();
lock (callbackState) { callbackState.Timer.Dispose(); }
}, state, millisecond, -1);
}
Блокировка должна препятствовать попытке обратного вызова таймера освободить таймер до того, как установлено поле Timer
.
Добавление: Как указал комментатор, если action()
что-то делает с пользовательским интерфейсом, тогда лучше использовать System.Windows.Forms.Timer
, поскольку он будет выполнять обратный вызов в потоке пользовательского интерфейса. Однако, если это не так, и он до Thread.Sleep
против Threading.Timer
, Threading.Timer
- путь.