Я новичок в C# и пытаюсь создать простую программу тренировки мозга с использованием Windows Forms, которую я изучил, изучая разработку приложений для Android. Я застрял на таймере. У меня он работает, он срабатывает каждую секунду и обновляет метку в моей форме. Когда я добавляю код после запуска таймера, таймер останавливается. Как будто я не работаю в фоновом режиме. Я много читал о таймерах потоковой передачи, таймерах и т. д., Но мне не удалось заставить что-либо работать. Как я уже сказал, я новичок в C#, поэтому будьте осторожны ... Он мой код ....
public partial class BrainTrainer : Form
{
// Set global timer variables & Create Timer
static int secondCounter = 10;
static bool play = false;
static Timer myTimer = new Timer();
public BrainTrainer()
{
// Set up form
InitializeComponent();
toggleLabels(false);
timerLbl.Text = secondCounter.ToString() + "s";
}
// Function to loop through labels and disabled them
private void toggleLabels(bool state)
{
var ansLabels = this.Controls.OfType<Label>()
.Where(c => c.Name.StartsWith("ans"))
.ToList();
foreach (var label in ansLabels)
{
label.Enabled = state;
}
}
// Event to run every second
private void TimerEventProcessor(Object myObject, EventArgs e)
{
if (secondCounter == 0)
{
//Stop Game
myTimer.Stop();
play = false;
}
else
{
// Countdown 1 and update label
secondCounter--;
timerLbl.Text = secondCounter.ToString()+"s";
}
}
private void startBtn_Click(object sender, EventArgs e)
{
// Hide button, set play to true and enable labels
startBtn.Hide();
play = true;
toggleLabels(true);
// Set up timer event, interval and start
myTimer.Tick += new EventHandler(TimerEventProcessor);
myTimer.Interval = 1000;
myTimer.Start();
// Run function to play
genEquation();
}
private void genEquation()
{
while (play)
{
Console.WriteLine(secondCounter);
}
}
}
Мы будем очень благодарны за любую помощь или ссылку на полезное руководство!
таймер похож на метроном в тике, он что-то делает, но при следующем тике он ничего не делает. Так, например, таймер установлен на 15 секунд и в билете, чтобы показывать дату / время на этикетке, будет обновляться каждые 15 секунд .. больше ничего не происходит.
Вы добавляете подписку на событие каждый раз, когда нажимаете кнопку, что может вызвать серьезные ошибки.
@ Клеменс, не могли бы вы указать правильное направление таймера отправки, поскольку, когда я попробовал это, я не смог заставить его работать.
@BugFinder, спасибо, я понял. Но галочка перестает «тикать», когда я запускаю код после запуска таймера.
@FindOutIslamNow, как бы мне это сделать. Я попытался поместить .tick
и .interval
вне функции, где я инициализировал таймер, но он не принял его.
@FindOutIslamNow, отсортировал. Вставьте основной метод.
Трудно сказать, но правильно ли это работает в первый раз? Или вообще не работает?
Вы знаете, что это не WPF
, и на самом деле вы используете Winforms
.
Просто предположение: вы блокируете текущий поток и не даете ему времени на обработку .Tick-Event. Winforms-Timer не запускает для этого поток. Попробуйте вызвать Application.DoEvents () в цикле genEquation (), чтобы обработать событие.
Нет, вообще не побежит. Если я не включу genEquation()
. Все работает нормально, мой таймер работает и отсчитывает, обновляет метку и т. д. Как только я пытаюсь запустить genEquation()
, который представляет собой цикл, таймер останавливается. Если я удалю цикл и просто заставлю эту функцию отображать окно сообщения, она сработает. Это как-то связано с многопоточностью? Если да, то как мне обойти это, не зная об этом!
@Hyarus, вот и все. Работаю сейчас! Ваше здоровье!!!
Спасибо, @Franck, сказал, что я полный C# noob ;-)
Проблема решена в комментариях
Вы блокируете текущий поток и не даете ему времени на обработку .Tick-Event. Winforms-Timer не запускает для этого поток. Попробуйте вызвать Application.DoEvents () в цикле genEquation (), чтобы обработать событие.
private void genEquation()
{
while (play)
{
Application.DoEvents();
Console.WriteLine(secondCounter);
}
}
Если вы хотите изменить какие-либо элементы пользовательского интерфейса из обратного вызова таймера, используйте класс DispatcherTimer.