Сегодня мы изучаем многопоточность на уроке и столкнулись с очень любопытной ошибкой. При выполнении цикла for в нашем новом потоке верхняя граница цикла for продолжает передаваться. Поток уничтожается, но затем появляется другое значение и завершается другой поток.
В целях отладки ошибки я изменил верхнюю границу на 90, чтобы избежать исключения OutOfRange Exception на индикаторе выполнения.
При выводе счетчика на индикатор выполнения и обновлении индикатора выполнения я получил это в своем окне вывода.
Если я прокомментировал обновление на индикаторе выполнения (pbLoad.Value = i;
), я получил это в своем окне вывода.
Я попытался изменить цикл на i<101
, а также попытался переместиться туда, где был i++
, но это не имело никакого значения.
РЕДАКТИРОВАТЬ: Это исходит из файла BeginInvoke
. Когда я переключил его на Invoke
, это сработало, но затем я попаду в тупик при попытке использовать кнопку отмены.
Вот код:
public partial class Form1 : Form
{
Thread backgroundThread;
bool stopExecution = false;
public Form1()
{
InitializeComponent();
}
private void btnStart_Click(object sender, EventArgs e)
{
stopExecution = false;
btnStart.Enabled = false;
backgroundThread = new Thread(DoDomethingThatTakesAWhile);
backgroundThread.Start();
}
private void DoDomethingThatTakesAWhile()
{
for (int i = 0; i <= 100; i++)
{
if (!stopExecution)
{
Thread.Sleep(100);
if (pbLoad.InvokeRequired)
{
MethodInvoker myMethod
= new MethodInvoker(
delegate
{
if (!stopExecution)
{
pbLoad.Value = i;
Debug.WriteLine(i); //i to output window
}
});
pbLoad.BeginInvoke(myMethod);
}
else
{
pbLoad.Value = i;
}
}
else
{
break;
}
}
}
private void btnCancel_Click(object sender, EventArgs e)
{
//backgroundThread.Abort();
stopExecution = true;
backgroundThread.Join();
pbLoad.Value = 0;
btnStart.Enabled = true;
}
}