Натолкнулся на проблему которую не могу решить. Есть обработчик кнопки и в ней код, timer используется как контролл из ToolBox на форме. Обрабатывается таблица Excel, данные записываются в БД, нужен Прогрессбар для визуализации Ниже код:
timer1.Enabled = true; // Enable the timer.
timer1.Interval = 5;
timer1.Tick += new EventHandler(timer1_Tick);
timer1.Start();//Strart it
for (int i = 1; i <= 21; i++)
{
//код обработки и записи в БД
}
//конец обработки выборки из таблицы Excel
MessageBox.Show("!!!");
Текст обработчика timer1:
private void timer1_Tick(object sender, EventArgs e)
{
if (progressBar1.Value != int.Parse(textBox2.Text))
{
progressBar1.Value++;
}
else
{
timer1.Stop();
}
}
Но вот какое дело - специально поставил для наглядности интервал 5 миллисекунд, однако MessageBox.Show выскакивает ранее чем вызов обработчика timer. В чем причина?
Ваш код выполняется в потоке UI. При этом все вызовы таймера ставятся в очередь которую этот самый поток UI и разгребает. Вот и получается: пока код не отработает - таймер спит.
Чтобы ваш прогресбар работал - нужно либо наставить в цикле костылей в виде Application.DoEvents()
, либо вынести долгую обработку в отдельный поток. Проще всего это сделать при помощи задач (Tasks) а асинхронного программирования:
// метод в котором выполняется этот код надо отметить как асинхронный (async)
timer1.Enabled = true; // Enable the timer.
timer1.Interval = 5;
timer1.Tick += new EventHandler(timer1_Tick);
timer1.Start();//Strart it
await Task.Run(() =>
{
// Долгий код
});
MessageBox.Show("!!!");
Альтернативный вариант - можно заменить все внешние вызовы (например, обращение к БД) асинхронными операциями, оставшись при этом в потоке UI.
Необходимо задать собственную систему координат в CanvasЗначения X и значения Y не будут одинакового типа