C# — Таймер в Консольном Приложении


Таймеры

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

Пространство имен Описание
System.Threading Класс Timer из пространства имен System.Threading предлагает ключевую функциональность. В его конструкторе можно передавать делегат, который должен вызываться через указываемый интервал времени.
System.Timers Класс Timer из пространства имен System.Timers является компонентом, потому что унаследован от базового класса Component. Благодаря этому, его можно перетаскивать из окна Toolbox (Панель инструментов) в область проектирования серверного приложения, например, Windows-службы. Этот класс Timer использует класс System.Threading.Timer, но вместо делегатов предоставляет механизм на основе событий.
System.Windows.Forms В случае использования классов Timer из пространства имен System.Threading и System.Timers методы обратного вызова или событий инициируются не из вызывающего, а из другого потока. Элементы управления Windows Forms привязываются к потоку создателя. Обратный вызов в этот поток как раз и позволяет осуществлять класс Timer из пространства имен System.Windows.Forms.
System.Web.UI Класс Timer из пространства имен System.Web.UI является расширением Ajax и предназначен для использования с веб-страницами.
System.Windows.Threading Класс DispatcherTimer из пространства имен System.Windows.Threading применяется в WPF-приложениях и выполняется в рамках потока пользовательского интерфейса.

В случае применения класса System.Threading.Timer подлежащий вызову метод может передаваться прямо в первом параметре конструктора. Этот метод должен обязательно удовлетворять требованиям делегата TimerCallback, согласно которым возвращаемым типом должен быть void, а типом параметра — object. Во втором параметре может передаваться любой объект, который затем будет получен с аргументом объекта в методе обратного вызова.

Например, это может быть объект Event, который будет отправлять вызывающему классу соответствующий сигнал. В качестве третьего параметра указывается промежуток времени, через который метод обратного вызова должен вызываться в первый раз, а в качестве четвертого и последнего — промежуток времени, через который метод обратного вызова должен вызываться повторно. Если необходимо, чтобы таймер сработал только один раз, в четвертом параметре должно быть указано значение -1. Для изменения промежутка времени после создания объекта Timer служит метод Change().

Для целей иллюстрации предположим, что имеется консольное приложение, которое выводит текущее время каждую секунду до тех пор, пока пользователь не нажмет клавишу для прекращения приложения:

C# — Таймер в Консольном Приложении

Доброго времени суток! В этой статье я расскажу об использовании таймера в программах, написанных на C#, а в конце мы напишем простейшую программу часы. Статья будет практического характера и для её понимания Вам нужно владеть начальными знаниями программирования на языке C# и работы с WindowsForms приложениями. Но сначала, я расскажу для чего же нужны таймеры в программах. Чаще всего, таймеры используют для периодического вызова определенного метода (подпрограммы). У компонента «Timer» есть специальное (и единственное событие) — «Tick». Вот обработчик этого события, далее обработчик таймера, и вызывается с заданной программистом периодичностью.

Как я уже сказал, рассказ о таймерах будет в контексте WindowsForms. Так что я предлагаю создать новый проект приложения с графическим интерфейсом (WindowsForms). После чего, на главную форму из панели инструментов перенести компонент «Timer». Расположение компонента «Timer» в панели инструментов показано на рисунке ниже.

Данный компонент не является видимым на форме, поэтому, в дизайнере форм Вы его не увидите, но он будет в неком контейнере по формой, как показано на рисунке ниже.

Компонент Timer в дизайнере (под формой)

И если выбрать данный компонент в дизайнере форм, то можно увидеть его свойства, которых не так много — всего шесть. Я расскажу о самых важных, которые мы будем использовать. А сейчас, давайте посмотрим на свойства таймера (см. рисунок ниже).

Свойства компонента Timer

  • Свойство «Name» задает название таймера (скорее даже его уникальное имя, так как на форме может быть не один такой компонент);
  • Свойство «Eneble» делает таймер доступным (если установлено в true) или наоборот — недоступным (если установлено в false);
  • Свойство «Interavl» задает интервал, через который будет периодически вызываться обработчик таймера.


Так же у компонента «Timer» есть два интересующих нас метода:

  • Start — запускает таймер (после вызова этого метода, будет периодически «срабатывать» обработчик таймера);
  • Stop — останавливает таймер (после вызова этого метода, обработчик таймера перестанет «срабатывать» ).
Цукерберг рекомендует:  Oracle sql - Сравнение СУБД

А вот и то самое событие «Tick»:

Событие (Tick) таймера

А теперь, давайте приступим к практике. Для наглядности, я решил написать программу часы. Конечно, полноценными часами эту программу назвать нельзя, но она будет показывать время. Причем, не всегда, а только когда мы запустим таймер, который будет «срабатывать» раз в секунду, и выводить текущее время в надпись на форме. Для запуска и остановки таймера будут использоваться две кнопки.

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

Главное окно программы

Как видите, программа максимально простая: две кнопки, да текстовая надпись. А теперь, давайте перейдем к коду. Я создал обработчики событий клика для каждой копки и события «Tick» таймера. Код приведен ниже:

Всё довольно просто! А вот так будет выглядеть запущенная программа после нажатия на кнопку «Старт».

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

Я использую system.Timers Timer в консольном приложении для прослушивания Asynchronous Socket. Я хочу, чтобы таймер запускался каждые 40 секунд и проверял состояние подключения клиентских устройств.

После запуска таймера сокет сервера не прослушивание (не ожидая больше подключений), и только 1-е устройство, которое было подключено, может постоянно получать только данные. Когда я вынул устройство из сети и снова подключился, ничего не происходило. Никакая другая функция не работает. Вот код для таймера —

Таймер не должен влиять на мои другие функции. Он должен работать в фоновом режиме до тех пор, пока приложение не будет работать.

РЕДАКТИРОВАТЬ: (в приведенном выше коде) Добавлен, если CLients.Count > 0 только тогда удалит элемент из CLients, так что исключений там не будет.

При наличии соединения я добавляю объект State в словарь, чтобы при необходимости передавать данные всем клиентам.

Как вы можете видеть .. Если клиент вернулся в сеть, а сервер всегда находится в режиме прослушивания, он должен принять соединение, и объект состояния должен быть снова добавлен в клиент (объект словаря). Это не должно быть проблемой. И как только клиент подключается, я присваиваю IPStatus (объекту словаря) значение 1, поскольку это означает, что клиент находится в сети.


Затем в моем readCallBack () всякий раз, когда я получаю данные от любого клиента, затем в моем словарь, я снова устанавливаю его значение на 1 в IPStatus.

И когда таймер запускается, если значение любого IP равно 1, я устанавливаю его на 0. Так что в следующий раз если таймер работает и получает значение 0, это означает, что он не получил никаких данных от клиента за последние 35 секунд, что означает, что клиент больше не в сети. ReadCallback и все происходит с использованием StateObject, а не с клиентами (dictinary Object). Поэтому, если я удаляю какой-либо элемент из клиентов, я добавляю его снова, когда запускается любое новое соединение.

Надеюсь, мой сценарий станет более понятным для вас, ребята.

How do you add a timer to a C# console application?

a hFZr d u Nx b C y TKoab RVeqH J i e BSv t AxVt B tI r M a B i wmTn n PZyN s rDB

Answer Wiki

You Can Use: Use the System.Threading.Timer class.

Here’s an example of a timer in a console application:

public static class Program

public static void Main()

Console.WriteLine(«Main thread: starting a timer»);

Timer t = new Timer(ComputeBoundOp, 5, 0, 2000);

Console.WriteLine(«Main thread: Doing other work here. «);

Thread.Sleep(10000); // Simulating other work (10 seconds)

t.Dispose(); // Cancel the timer now

// This method’s signature must match the TimerCallback delegate

private static void ComputeBoundOp(Object state)


// This method is executed by a threa.

таймер в консольном приложении

Я создаю приложение устройства, используя.NET компактную структуру 2.0. Есть system.threading.timer в моем заявлении, которое выполняет некоторый код. Это хорошо работает. Моя проблема состоит в том, когда я управляю приложением, дважды щелкая по exe в папке мусорного ведра, запусках таймера и выполняю все, что это работает, но это никогда не останавливается. Это бежит в фоновом режиме даже за закрытием приложения при нажатии на X-button или из меню файла близкая кнопка. Я не понимаю, как и где я останавливаюсь или избавляюсь от таймера так, чтобы он не бежал за закрытием приложения. Может быть что-то как form_closing событие в приложении форм окна. Я искал много в Google, но не нашел надлежащего ответа.

Применение — использование, чтобы произвести цифровой выход для устройства вот некоторый код события таймера:

Это хорошо работает, когда я управляю кодом в режиме отладки, остановки таймера, когда я останавливаю программу. Но не работая, когда я управляю exe.

Как сделать таймер, перезагружающий консольное приложение C#?

Я новичок в кодировании C#, и для моей первой программы я хочу иметь таймер, который перезагружает мое консольное приложение каждые 10 секунд. Является ли это возможным? Можете ли вы написать пример, пожалуйста?Как сделать таймер, перезагружающий консольное приложение C#?

Цукерберг рекомендует:  Случайные изображения при помощи Flexbox & JavaScript

Если это ваша первая программа, я бы начинал с «Hello World» или независимо от того, что вам предлагает хороший учебник или книга по программированию. – gunr2171

Что вы пытаетесь выполнить, перезапустив приложение? –

Программы «hello world» не были бы полезны для программистов, имеющих опыт работы на других языках. – MxyL

ответ

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

Как я могу использовать таймер в моем консольном приложении?

Как я могу использовать таймер в моем консольном приложении? Я хочу, чтобы мое консольное приложение для работы в фоновом режиме и сделать что-то каждые 10 минут, например.

Как я могу это сделать?

Консольные приложения не обязательно означает, что давно работает. При этом, вы можете сделать это. Для того, чтобы убедиться, что консоль не просто выйти, вы должны иметь цикл консоли на Console.ReadLine ждать какой-то выходной строки, как «бросить курить».

Для того, чтобы выполнить свой код каждые 10 минут, вызовите System.Threading.Timer и указать его в метод выполнения с 10 минутным интервалом.


РЕДАКТИРОВАТЬ

Мне нравится комментарий Boj по вашему вопросу, хотя. Если вам действительно нужно длительный запущенное приложение, рассмотрит накладные делает его службу Windows. Там какая-то над головой развития, но вы получите гораздо более стабильной платформы, на которой для запуска кода.

Timers in .Net

В последнее время не в первый раз сталкиваюсь с тем, что разработчики не до конца понимают как работает один из стандартных таймеров в .NET — System.Threading.Timer.
Т.е. в общем-то они вроде понимают что таймер что-то выполняет, скорее всего в ThreadPool — и если его использовать для периодического выполнения чего-либо, то он вполне подойдет. Но вот если вам надо создать не один таймер, а положим 1000, то тут люди начинают волноваться: а вдруг вот что-то там не так, а вдруг это все-таки 1000 потоков и даже боятся использовать их в таких случаях.

Хотелось бы пролить немного света на этот «таинственный» System.Threading.Timer.

В .NET еще существуют другие таймеры, но они в основном предназначены для решения специфических задач(например, для написания GUI приложений). Нами рассматриваемый предназначен для решения «системных» задач или использования в библиотеках.

Немного о том, как бы мы могли реализовать таймер.

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

Можно было бы пойти другим путем и использовать объект ядра «таймер». Для каждой периодической единицы работы создавать объект ядра и в отдельном потоке ожидать на них в стиле:

Но, к сожалению или нет, в .NET нет API для прямой работы с такими объектами(таймерами ядра).

Есть третий вариант реализации таймера(получившийся у разработчиков класса System.Threading.Timer)
При создании первого в домене приложения таймера через механизм P/Invoke создается объект ядра «таймер» это можно увидеть в классе System.Threading.TimerQueue:

Также создается отдельный поток который высчитывает сколько надо подождать до ближайшего срабатывания одного из таймеров, устанавливает соответствующие параметры объекту ядра «таймер» и ждет.
Давайте посмотрим как это выглядит. Создадим консольный проект и подключим SOS Debugging Extension.

Как мы видим, перед созданием таймера у нас всего два потока: «основной» и поток «финализатора». Давайте продвинемся на одну строку ниже.

У нас появились два потока — один, ID 3, это как раз и есть поток который работает с объектом ядра «таймер». А второй, ID 4, это рабочий поток пула, он еще не успел запуститься, в нем будут исполняться наши callback.

Теперь как это все работает если вы последовательно создаете несколько таймеров
Возвращаемся к классу System.Threading.TimerQueue. Он является синглтоном. Каждый раз когда вы пишете код вида:

Это приводит к добавлению экземпляра класса System.Threading.TimerQueueTimer в его внутреннюю очередь(являющуюся чем-то вроде LinkedList). Т.е. этот класс содержит внутри себя все созданные таймеры(я склоняюсь что в рамках домена).
После того как первый таймер был создан. У TimerQueue будет регулярно вызыватьcя метод FireNextTimers.
Что он делает(код длинный, я не стал приводить исходники, кому интересно может посмотреть сам):
Он быстро пробегается по всем сохраненным в нем таймерам и находит время до ближайшего срабатывания таймера и настраивает объект ядра таймер на посылку нотификации через этот интервал. Как только эта нотификация будет получена, время следующего срабатывания будет пересчитано и объект ядра таймер будет настроен на новый интервал. При добавлении нового таймера время следующей нотификации будет пересчитано.

Давайте попробуем создать 1000 таймеров и посмотрим что из этого получится:

Цукерберг рекомендует:  Трудоустройство - Трудоустройство после курса Тестировщик ПО

Мы видим, что создание 1000 таймеров не влечет за собой создание 1000 потоков. CLR создало один поток для работы с таймером ядра и несколько рабочих потоков для обработки срабатываний таймера.


Итого:
Когда вы работаете с классом System.Threading.Timer создается один(на домен приложения) объект ядра «таймер» и один поток для работы с ним который работает по принципу схожему с работой структуры данных «куча».
К вопросу о 1000 таймеров — накладно ли создавать такое количество таймеров в приложении, думаю что каждый конкретный случай надо рассматривать отдельно. Но знание того как устроены таймеры изнутри поможет принять правильное решение.

Испытывалось на Windows 7 64, .Net 4.5, VS2012.
Используемая литература: Duffy «Concurrent Programming on Windows», MSDN

Как добавить таймер в консольное приложение С# — c#

Только это — Как добавить таймер в консольное приложение С#? Было бы здорово, если бы вы могли предоставить примерное кодирование.

    3 7
  • 12 окт 2020 2020-10-12 12:04:45
  • Johan Bresler

7 ответов

Вы также можете создать свой собственный (если недовольны доступными опциями).

Создание собственной реализации Timer — довольно простой материал.

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

Вы можете добавлять события следующим образом:

Чтобы убедиться, что таймер работает, вам необходимо создать бесконечный цикл следующим образом:

  • 12 окт 2020 2020-10-12 12:04:47

  • Steven de Salas

Вы также можете использовать свои собственные механизмы синхронизации, если хотите немного больше контроля, но, возможно, с меньшей точностью и большим количеством кода/сложности, но я бы по-прежнему рекомендовал таймер. Используйте это, хотя если вам нужно контролировать фактический поток времени:

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

и использовать/запустить можно:

Обратный вызов — это ваш метод без параметров, который вы хотите вызывать на каждом интервале. Например:

  • 12 окт 2020 2020-10-12 12:04:47
  • mattlant

Или используя Rx, короткий и сладкий:

  • 12 окт 2020 2020-10-12 12:04:47
  • Yonatan Zetuny

Получает немного удовольствия

  • 12 окт 2020 2020-10-12 12:04:47
  • Real Caz

Вот код для создания простого таймера с одним секундой:

И вот результат:

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

  • 12 окт 2020 2020-10-12 12:04:46
  • jussij

Используйте класс System.Threading.Timer.

System.Windows.Forms.Timer предназначен в первую очередь для использования в одном потоке, обычно в потоке пользовательского интерфейса Windows Forms.

В начале разработки .NET Framework также добавлен класс System.Timers. Однако обычно рекомендуется использовать класс System.Threading.Timer, поскольку это всего лишь оболочка в System.Threading.Timer в любом случае.

Также рекомендуется всегда использовать статический (совместно используемый в VB.NET) System.Threading.Timer, если вы разрабатываете службу Windows и требуете, чтобы таймер запускался периодически. Это позволит избежать возможной преждевременной сборки мусора вашего объекта таймера.

Вот пример таймера в консольном приложении:

Из книги CLR Via С# от Джеффа Рихтера. Кстати, эта книга описывает обоснование трех типов таймеров в главе 23, настоятельно рекомендуется.

  • 12 окт 2020 2020-10-12 12:04:46
  • Ash

Очень приятно, однако, чтобы имитировать некоторое время прохождения, нам нужно запустить команду, которая занимает некоторое время, и это очень ясно во втором примере.

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

Мы можем видеть эту модификацию в коде из той же книги CLR Via С# Third Ed.

таймер в консольном приложении

Я создаю приложение устройства, используя.NET компактную структуру 2.0. Есть system.threading.timer в моем заявлении, которое выполняет некоторый код. Это хорошо работает. Моя проблема состоит в том, когда я управляю приложением, дважды щелкая по exe в папке мусорного ведра, запусках таймера и выполняю все, что это работает, но это никогда не останавливается. Это бежит в фоновом режиме даже за закрытием приложения при нажатии на X-button или из меню файла близкая кнопка. Я не понимаю, как и где я останавливаюсь или избавляюсь от таймера так, чтобы он не бежал за закрытием приложения. Может быть что-то как form_closing событие в приложении форм окна. Я искал много в Google, но не нашел надлежащего ответа.

Применение — использование, чтобы произвести цифровой выход для устройства вот некоторый код события таймера:

Это хорошо работает, когда я управляю кодом в режиме отладки, остановки таймера, когда я останавливаю программу. Но не работая, когда я управляю exe.

Понравилась статья? Поделиться с друзьями:
Все языки программирования для начинающих