Повтор функции каждые несколько секунд

Я хочу повторять функцию с момента открытия программы до ее закрытия каждые несколько секунд. Как лучше всего это сделать на С#?


person Community    schedule 02.07.2012    source источник


Ответы (4)


Используйте таймер. Существует 3 основных вида, каждый из которых подходит для разных целей.

Используйте только в приложении Windows Form. Этот таймер обрабатывается как часть цикла сообщений, поэтому таймер может зависнуть при высокой нагрузке.

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

Это самый мощный таймер, запускающий тики в фоновом потоке. Это позволяет выполнять операции в фоновом режиме, не останавливая графический интерфейс или основной поток.

В большинстве случаев я рекомендую System.Timers.Timer.

person Kendall Frey    schedule 02.07.2012
comment
Просто дополнение — на самом деле их больше, чем просто это — например, есть DispatcherTimer (WPF/Silverlight), а также другие инструменты, такие как таймеры. - person Reed Copsey; 02.07.2012
comment
Также обратите внимание, что истекшее событие System.Timers.Timer срабатывает в потоке пользовательского интерфейса, если вы устанавливаете SynchronizingObject, в противном случае оно срабатывает в потоке ThreadPool. - person Ed Power; 02.07.2012
comment
Следует отметить, что если вам нужна надежность, ни один из них не работает в 100% случаев, особенно в системах с большой нагрузкой. - person Vasily Sliounaiev; 18.02.2016
comment
Важное примечание от MSDN: класс Timer доступен только в .NET Framework. Он не включен в стандартную библиотеку .NET и недоступен на других платформах, таких как .NET Core или универсальная платформа Windows. На этих платформах, а также для обеспечения переносимости между всеми платформами .NET вместо этого следует использовать класс System.Threading.Timer. - person JPelletier; 22.08.2016
comment
@JPelletier Спасибо, этот комментарий избавил меня от многих головных болей. - person Bailey Miller; 19.10.2016

Для этого лучше всего подходит System.Timers.Timer

// Create a timer
myTimer = new System.Timers.Timer();
// Tell the timer what to do when it elapses
myTimer.Elapsed += new ElapsedEventHandler(myEvent);
// Set it to go off every five seconds
myTimer.Interval = 5000;
// And start it        
myTimer.Enabled = true;

// Implement a call with the right signature for events going off
private void myEvent(object source, ElapsedEventArgs e) { }

Дополнительные сведения см. в разделе класс таймера (.NET 4.6 и 4.5).

person IvoTops    schedule 02.07.2012
comment
Для тех, кто ищет консоль для быстрого копирования и вставки, я использовал пример @IvoTops и создал образец здесь -> gist.github.com/HockeyJustin/1161699bd26adb5c054d . - person HockeyJ; 06.02.2015

Используйте таймер. Имейте в виду, что .NET поставляется с несколькими различными таймерами. Эта статья покрывает различия.

person Brian Rasmussen    schedule 02.07.2012
comment
Ссылка на журнал MSDN не работает. - person Josh Noe; 31.08.2016

В .NET BCL есть много разных таймеров:

Когда какой использовать?

  • 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.Windows.Threading.DispatcherTimer, таймер, встроенный в очередь Dispatcher. Этот таймер обрабатывается с указанным приоритетом в указанный интервал времени.

Источник


Некоторым из них требуется явный вызов Start, чтобы начать отсчет (например, System.Timers, System.Windows.Forms). И явный Stop, чтобы закончить отметку.

using TimersTimer = System.Timers.Timer;

static void Main(string[] args)
{
    var timer = new TimersTimer(1000);
    timer.Elapsed += (s, e) => Console.WriteLine("Beep");
    Thread.Sleep(1000); //1 second delay
    timer.Start();
    Console.ReadLine();
    timer.Stop();

}

Хотя, с другой стороны, есть некоторые таймеры (например: System.Threading), где вам не нужны явные вызовы Start и Stop. (Предоставленный делегат запустит фоновый поток.) ​​Ваш таймер будет тикать до тех пор, пока вы или среда выполнения не избавитесь от него.

Таким образом, следующие две версии будут работать одинаково:

using ThreadingTimer = System.Threading.Timer;

static void Main(string[] args)
{
    var timer = new ThreadingTimer(_ => Console.WriteLine("Beep"), null, TimeSpan.FromSeconds(1), TimeSpan.FromSeconds(1));
    Console.ReadLine();
}
using ThreadingTimer = System.Threading.Timer;
static void Main(string[] args)
{
    StartTimer();
    Console.ReadLine();
}

static void StartTimer()
{
    var timer = new ThreadingTimer(_ => Console.WriteLine("Beep"), null, TimeSpan.FromSeconds(1), TimeSpan.FromSeconds(1));
}

Но если ваш timer утилизирован, то он, очевидно, перестанет тикать.

using ThreadingTimer = System.Threading.Timer; 

static void Main(string[] args)
{
    StartTimer();
    GC.Collect(0);
    Console.ReadLine();
}

static void StartTimer()
{
    var timer = new ThreadingTimer(_ => Console.WriteLine("Beep"), null, TimeSpan.FromSeconds(1), TimeSpan.FromSeconds(1));
}
person Peter Csala    schedule 04.12.2020