Я пытался обновить статус в пользовательском интерфейсе для Long Running Operating. Я создал приложение на основе демо-формы, задание имеет несколько строк, каждая строка имеет дни и значения по умолчанию в каждом столбце datagrid равна 0, как только файл вычисления вычисляет одну итерацию на один день, он обновит пользовательский интерфейс и установит 1 для этого день.Сжигание событий в цикле не обновляет пользовательский интерфейс в последовательности
Я использую потоки, делегаты и события для реализации этого, и он работает как ожидается, если я поставлю Thread.Sleep (100) между двумя вызовами событий. Если я поставлю «Thread.Sleep (100)» внутри последнего вложенного цикла, то он обновит интерфейс, как ожидалось, но как только я удалю его и запустил цикл без сна, он пропускает некоторые из столбцов в пользовательском интерфейсе и напрямую обновляет последние несколько/случайные столбцы, как вы можете видеть в прикрепленной ссылке изображения (изображение вывода моего кода без спящего потока) обновляется только последний столбец.
Если я не ошибаюсь, все события запускаются последовательно, тогда они также должны обновлять пользовательский интерфейс, но это не происходит, и я не знаю почему. Я не хочу делать это спящим, потому что у меня есть около 14 вызовов в реальном приложении для обновления статуса пользовательского интерфейса, и он будет работать под циклом, поэтому, если он поставит сон (100), это будет стоить мне много, есть ли способ сделать это без SLEEP?
Image of output of my code without thread sleep
public class Class1 : IGenerate
{
public event MessageEventHandler OnMessageSending;
public void LongOperationMethod(BindingList<Status> _statusData)
{
if (OnMessageSending != null)
{
MessageEventArgs me = new MessageEventArgs();
/// Loop for 2-3 Weeks
for (; ;){
/// Loop for 7 day
for (; ;)
{
/// Calculation on everyday
for (int j = 0; j != 1000; ++j)
{
// to do
}
me.weekNo = k;
me.DayNo = i;
OnMessageSending(me);
}
}
me.Message = "Process completed successfully...";
OnMessageSending(me);
}
else
{
throw new ArgumentException("Event hasn`t been rised, so we cannot continue working.");
}
}
}
**UI file:**
<pre><code>
public partial class Form1 : Form
{
BindingList<Status> _statusData = new BindingList<Status>();
delegate void StringParameterDelegate(string value);
Class1 cls = new Class1();
public Form1()
{
InitializeComponent();
labelProgress.Text = "";
}
private void button1_Click_1(object sender, EventArgs e)
{
for (int i = 1; i <= 2; ++i)
{
_statusData.Add(new Status { Week = "Week" + i, Day1 = 0, Day2 = 0, Day3 = 0, Day4 = 0, Day5 = 0, Day6 = 0, Day7 = 0 });
}
dataGridView1.DataSource = _statusData;
}
private void button2_Click(object sender, EventArgs e)
{
Thread t1 = new Thread(() => StartingThread(_statusData));
t1.Start();
}
void StartingThread(BindingList<Status> _statusData)
{
IGenerate generate = new Class1();
generate.OnMessageSending += new MessageEventHandler(generate_OnMessageSending);
generate.LongOperationMethod(_statusData);
}
private void generate_OnMessageSending(MessageEventArgs e)
{
int weekNo = e.weekNo;
int dayNo = e.DayNo;
this.dataGridView1.BeginInvoke(new MethodInvoker(() => dataGridView1.Rows[e.weekNo].Cells[e.DayNo + 1].Value = 1));
this.labelProgress.BeginInvoke(new MethodInvoker(() => this.labelProgress.Text = e.Message));
}
}
</code></pre>