Как сделать задержку в windows forms

Обновлено: 07.07.2024

Иногда в приложениях, работающих в графическом интерфейсе Windows, возникает необходимость отображения текущего времени суток (часы:минуты:секунды). Для реализации этой задачи в аппаратуре компьютера предусмотрен доступ к таймеру.

Программируемый таймер предназначен для получения программно-управляемых временных задержек и генерации функций, задающих время. Программируемый таймер разрешает формировать заданные интервалы времени независимо от быстродействия вычислительной системы. По умолчанию, операционная система Windows вызывает прерывание от таймера 18,2 раза за секунду.

Система Microsoft Visual Studio представляет для пользователя элемент управления Timer , реализующий выполнение прерывания от таймера.

Также с помощью компонента Timer можно организовать параллельное выполнение различных процессов в программе.

В данном примере показано, как использовать компонент Timer для вывода на форме текущего времени. Также показано как можно управлять таймером, останавливая и продолжая показ текущего времени.

Выполнение

1. Создание проекта по шаблону Windows Forms Application .

Запустить MS Visual Studio . Создать проект по шаблону Windows Forms Application . Подробный пример создания проекта по шаблону Windows Forms Application описывается здесь .

2. Создание главной формы.

Создать форму, как показано на рисунке 1.

Разместить на форме следующие компоненты:

  • компонент типа Label . Создается объект (экземпляр класса) с именем label1 ;
  • два компонента типа Button . Создается два объекта с именами button1 и button2 ;
  • компонент типа TTimer (рисунок 1). Создается объект с именем timer1 .
3. Настройка компонент типа Label и Button .

Настроить следующие свойства компонент Label и Button :

Если пользователь сделает клик на кнопке button1 (начало отсчета), часы реального времени будут включены. При клике на кнопке button2 время будет остановлено.

После настройки элементов управления форма будет иметь вид как показано на рисунке 2.

4. Настройка компонента типа Timer .

В компоненте Timer свойство Interval установить в значение 100 (рисунок 3) или в любое другое значение. Значение Interval измеряется в миллисекундах. Interval задает частоту вызова обработчика события, то есть частоту изменения значения часов реального времени.

Рис. 3. Свойство Interval элемента управления Timer

5. Программирование обработчика события Tick .

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

Листинг обработчика timer1_Tick() события Tick следующий:

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

6. Программирование событий клика на кнопках Button1 и Button2 .

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

Обработчик события клика на кнопке Button1 имеет вид:

Чтобы остановить таймер, нужно свойство Enabled элемента управления Timer установить в значение false .

7. Запуск программы на выполнение.

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

Если в программе нужно постоянно отображать текущее время, тогда строку

можно разместить в начале загрузки формы (в конструкторе или в обработчике события Load ).

Никак не получается решить одну задачу. Допустим, есть форма с одной кнопкой. Нужно, чтобы через 3 секунды после нажатии на эту кнопку надпись на ней менялась. Я знаю, что это очень легко делается с помощью таймера, но в моем случае все не так просто. Мне нужно, чтобы при нажатии на кнопку в обработчике этой кнопки вызывался этот таймер, и по завершении его (таймера) работы (через 3 секунды) обработчик продолжил выполняться. Я пробовал сделать задержку Thread.Sleep(3000) и после нее изменить надпись, но в таком случае форма зависает на 3 секунды, что, в принципе, логично. Вопрос в том, как сделать, чтобы она не зависала?

Заранее благодарен за помощь

Как сделать задержку в программе?
Dalay в программе. Как установить заданный timeout?

Как правильно сделать задержку, ожидать событие в программе?
Вот, к примеру, алгоритм: Запуск программы Подготовка данных Запуск стороннего приложения.

Как сделать задержку без загрузки процессора?
В общем хочу сделать менюшку в Ацессе, таким образом, чтобы при наведении на кнопочку, но не.

ViktorKozlov, необходимо выносить задачу в отдельный поток (смотри "многопоточное выполнение задач") ViktorKozlov, необходимо выносить задачу в отдельный поток (смотри "многопоточное выполнение задач") Но форма вообще навсегда зависает. Я так понимаю, это происходит потому, что в отдельном потоке вызывается только функция ff, а обработчик таймера к нему не имеет никакого отношения, хотя проблема, наверное, в другом. Можете сказать, какая здесь ошибка или предложить альтернативный вариант?

То, что вы хотите - невозможно. Нельзя создать команду, которая будет чего-то ждать 3 секунды, не блокируя при этом поток. Но можно сделать видимость активности формы, примерно так:

Добавлено через 54 секунды
Но лучше воспользоваться отдельным потоком и в нем просто вызвать

ахах, manualEventReset.
Зачем? ты используешь фоновый поток, и при вызове ManualEventReset.Wait все равно блокируешь текущий поток, то есть ты сводишь на нет использование этого фонового потока. убери его.

Добавлено через 5 минут
В фоновом потоке:

Добавлено через 2 минуты
при этом основной поток не будет виснуть

Еще один способ, не совсем адекватный конечно, но имеет право на жизнь:

Всем спасибо, вроде понятнее стало

Только теперь не могу понять другое:

Я хочу, чтобы выполнялся цикл

т.е. каждые полсекунды надпись на кнопке увеличивается на единицу. Если поместить этот цикл в обработчик нажатия этой кнопки, то форма зависнет на время выполнения этого цикла и потом надпись сразу станет 20. Но если этот цикл поместить в функцию, которая будет вызываться в этом же обработчике в отдельном потоке, то надпись, как и нужно, обновляется каждые полсекунды, даже если не ставить button1.Refresh(). Я так понимаю, что в первом случае зависает потому, что после изменения свойства Text у кнопки перерисовка сразу не вызывается, а встает в очередь, так как этот поток занят выполнением цикла, а во втором случае цикл идет в другом потоке, поэтому основной поток ничем не занят и все перерисовывает. Правильно ли я понимаю? И можно ли сделать, чтобы такой цикл работал без дополнительного потока? Пробовал ставить Application.DoEvents(), результат получше, но если вертеть формой, то процесс останавливается и возобновляется только если ее отпустить Я обычно делаю рабочий поток, отдельный от потока UI, и обновляю UI по событиям, происходящем в рабочем потоке, либо по таймеру.

Я уже писал способ выше:

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

Добавлено через 3 минуты
* корректно обновляется значение, но форма виснет

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

Не знаю, корректно ли это, но я сделал так:

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

Содержание:

Шаг 1

Откроем Visual Studio и создадим приложение Windows Forms.

Шаг 2

Добавим в форму два элемента управления Button и назовем их Start и Stop , хотя имена вы можете написать любые, по своему усмотрению. Окончательная форма выглядит следующим образом:

Шаг 3

Шаг 4

Теперь нам необходимо установить свойства нашего таймера. Для этого щелкнем правой кнопкой мыши на элементе управления « Timer » и откроем окно «Свойства». Здесь для вкладки Interval необходимо установить значение 1000, которое определяется в миллисекундах.

1 секунда = 1000 миллисекунд.

Шаг 5

Теперь нужно нажать кнопку Events и добавить обработчик событий Timer , дважды щелкнув по свойству Tick . Событие таймера здесь — timer1_Tick (как показано на изображении ниже).

Шаг 6

Теперь добавим классы FileStream и StreamWriter в начало нашей программы. Они используются для создания нового текстового файла и реализации записи данных в него. Все классы определены в библиотеке базовых классов System.IO , поэтому обязательно импортируйте System.IO в начале программы.

Мы видим из предыдущего участка кода, что класс FileStream создает файл mcb.txt на диске C , а StreamWriter определен для записи в него данных. Теперь напишем алгоритм реализации записи нескольких строк в наш файл:

Далее настроим два обработчика регулирующих нажатие кнопок Start и Stop . В примере ниже, для кнопки «Пуск» устанавливаем значение свойства таймера Enabled = true . Теперь при нажатии на нее будет запускаться таймер, регулирующий выполнение события.

Ту же процедуру проделываем и с кнопкой STOP , только в этом случае свойству Enabled устанавливаем значение false для прекращения выполнения нашего события.

Остался последний шаг — создать событие timer1_Tick , записывающее текущую дату в текстовый файл:

Шаг 7

Скомпилируем и запустим приложение. Затем нажмем кнопку «Пуск», чтобы начать запись в текстовый файл. Подождем примерно минуту, а затем нажмем кнопку «Стоп», чтобы остановить его работу. В выходном текстовом файле mcb.txt после всех манипуляций около 60 раз пропишется текущая дата и время. Это значит, что мы все сделали правильно.

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

Например: создадим такой таймер, установим ему необходимые свойства, а также добавим обработчик событий, интервал сделаем равным 2 секундам:

Допустим, мы хотим отобразить текст в элементе управления ListBox . Следующий код добавляет текст и обновляет ListBox каждые 2 секунды:

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

Событие в предыдущем примере будет запускаться каждые 5 секунд.

Резюме

Закрепить приведенный материал можно на базе таких видео:

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

Я невероятно новичок в программировании, и я достаточно хорошо учился до сих пор, я думаю, но я все еще не могу понять идею сделать задержку так, как я хочу. То, над чем я работаю, - это своего рода тестовая "игра" с использованием приложения Windows forms, которое включает боевую систему. В нем я хочу сделать NPC, который делает действие каждые пару секунд. Проблема в том, что я также хочу позволить игроку взаимодействовать между атаками. Нитка.кажется, сон не помогает мне, нет. только потому, что я не знаю, как многопоточный, но всякий раз, когда я пытаюсь запустить его, говорите так:

он, кажется, настаивает на том, чтобы сначала спать, а затем печатать обе строки.

как это работает, вы отмечаете функцию, нуждающуюся в асинхронных операциях, с помощью async ключевое слово. Это всего лишь подсказка компилятору. Затем вы используете await ключевое слово в строке, где вы хотите, чтобы ваш код выполнялся асинхронно, и ваша программа будет ждать без блокировки потока или пользовательского интерфейса. Метод, который вы вызываете (на линии ожидания), должен быть отмечен Ан async ключевое слово также и обычно называется, заканчивая асинхронным, как в ImportFilesAsync.

что вам нужно сделать в вашем примере:

ваш код сейчас готов к использованию Task.Delay метод вместо System.Threading.Thread.Sleep метод (можно использовать await on Task.Delay , потому что Task.Delay обозначен async в своем определении).

здесь вы можете узнать больше о задач.Задержка и ждут.

Извините, что разбудил такой старый вопрос. Но я думаю, что первоначальный автор хотел получить ответ:

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

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

в этом случае вы вносите изменения, приостанавливаете поток, а затем снова меняете текст, и когда поток, наконец, умирает .Update() уволен. Это приводит к тому, что вы видите только последнее изменение, внесенное в текст.

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

добавлять using System.Timers; в вашей программе вы можете использовать эту функцию:

задержка является функцией и может использоваться как:

таймеры могут обеспечить вам точность до 1 миллисекунды. В зависимости от интервала тика генерируется событие. Делайте свои вещи внутри события tick.

Читайте также: