Неправильно работает таймер WinForms
Я разрабатываю симулятор роста растений. Для каждого растения предусмотрено конкретное кол-во стадий и длительность одной стадии. Для прохождения по нескольким стадиям использую цикл for, в котором вызываю метод с таймером, где он описывается и запускается. Также, прописаны timer.Tick и Timer.Stop. Проблема состоит в том, что вместо того, чтобы включаться и тикать на каждой стадии роста (то есть при каждом вызове метода в цикле), он включается и тикает только на последней. Причем, во всех остальных стадиях проходит все строки метода, кроме Tick. И, таким образом, нарушается вся цепочка действий. Как это выглядит:
Инициализация массива растений выполнена Инициализация массива картинок выполнена Таймер запущен Стадия 0 пройдена Таймер запущен Стадия 1 пройдена Таймер запущен Стадия 2 пройдена Растение Подсолнух выросло Время 5 Время 4 Время 3 Время 2 Время 1 Время 0 Стадия пройдена
Ниже цикл, включающий в себя стадии роста растения. Plants.masPlants[0].CountSteps - кол-во стадий для этого растения. PlantGrowth - метод. Проверяет и определяет пройденные и не пройденные стадии растения. Возвращает текущую стадию/если стадия последняя -число 13.
for (int i = 0; i < Plants.masPlants[0].CountSteps; i++)
{
TimerStart(timer0, label_time0, textBox1);
var plantgrowstep = Plants.PlantGrowth(Plants.masPlants[0], i, textBox1);
PlantPicture.Image = new Bitmap(images[i]);
if (plantgrowstep==13)
{
textBox1.Text += $"Растение {Plants.masPlants[0].NamePlant} выросло\r\n";
//MessageBox.Show($"Растение {Plants.masPlants[0].NamePlant} выросло");
}
}
Метод таймера. Уже использовался в другом проекте. Работал, только там он не вызывался в цикле.
static int tk, p;
static string c;
public static void TimerStart(Timer timer, Label label, TextBox textBox)
{
p = 5;
c = "00:05";
label.Text = c;
timer.Interval = 1000;
timer.Enabled = true;
timer.Start();
textBox.Text += $"Таймер запущен\r\n";
timer.Tick += (sender, args) =>
{
textBox.Text += $"Время {p}\r\n";
tk = --p;
TimeSpan span = TimeSpan.FromMinutes(tk);
string label_time = span.ToString("hh':'mm");
label.Text = label.ToString();
if (p < 0)
{
timer.Stop();
textBox.Text += $"Стадия пройдена\r\n";
}
};
}
метод PlantGrowth: [] plant.GrowSteps - булевой массив для обозначения пройденных стадий.
public static int PlantGrowth(Plants plant, int i, TextBox textBox)
{
plant.GrowSteps[i] = true;
if (plant.GrowSteps[plant.CountSteps-1]==true)//если последняя стадия роста прошла
{
plant.IsPlantGrown = true;
textBox.Text += $"Стадия {i} пройдена\r\n";
return 13;
}
textBox.Text += $"Стадия {i} пройдена\r\n";
return i;
}
Я новичок, не судите строго.
Ответы (1 шт):
все правильно.
Вы в цикле запускаете ОДИН И ТОТ ЖЕ таймер.
Не успевает этот таймер что то сделать - как уже происходит следующая итерация цикла, и вы опять запускаете тот же самый таймер.
Если Вы хотите непременнно использовать таймер - нужно поменять архитектуру приложения, примерно так:
оставить один таймер, а уже в нём (точнее, в методе обработки события Tick) - запускать цикл по всем растениям.
Таким образом, у Вас на каждый тик таймера будет происходить симуляция одного шага роста всей популяции растений.