Обновление пользовательского интерфейса из фонового потока, который вызывается в цикле в основном пользовательском интерфейсе после завершения потока
У меня есть приложение WinForms, которое вызывает метод бизнес-класса, который выполняет некоторые тяжелые действия, занимая около 5 секунд для каждого вызова. Основная форма вызывает этот метод в цикле. Этот цикл может выполняться от 10 до 10 тысяч раз.
Приложение WinForms отправляет параметр в бизнес-класс и имеет область для отображения времени, необходимого для каждого вызова метода, и значения, возвращаемого методом. Как сообщить моему главному окну и обновить текстовую область в главной форме win с тем, что метод возвращал для каждого вызова?
В настоящее время данные поступают сразу после завершения всех потоков. Есть ли способ обновить пользовательский интерфейс для всех итераций цикла после завершения каждого вызова? Я не против, если это будет сделано также последовательно.
Форма
HeavyDutyClass hd;
public Form1()
{
InitializeComponent();
hd = new HeavyDutyClass();
}
//BUTTON CLICK
private void Start_Click(object sender, EventArgs e)
{
int filecount = 5000; //BAD - opening 5000 threads! Any other approach?
hd.FileProcessed += new EventHandler(hd_FileProcessed);
var threads = new Thread[filecount];
for (int i = 0; i < filecount; i++)
{
threads[i] = new Thread(() => { hd.LongRunningMethod(); });
threads[i].Start();
}
}
//BUSINESS CLASS EVENT THAT FIRES WHEN BUSINESS METHOD COMPELTES
void hd_FileProcessed(object sender, EventArgs e)
{
if (dgv.InvokeRequired)
{
dgv.Invoke((MethodInvoker)delegate { UpdateGrid(); });
}
}
private void UpdateGrid()
{
dgv.Rows.Add(1);
int i = dgv.Rows.Count;
dgv.Rows [ i-1].Selected = true;
dgv.FirstDisplayedScrollingRowIndex = i - 1;
}
Бизнес-класс HeavyDuty
public event EventHandler FileProcessed;
public HeavyDutyClass()
{
}
protected virtual void OnMyEvent(EventArgs e)
{
if (FileProcessed != null)
{
FileProcessed(this, e);
}
}
public bool LongRunningMethod()
{
for (double i = 0; i < 199990000; i++)
{
//time consuming loop
}
OnMyEvent(EventArgs.Empty);
return true;
}