Причина, по которой это не работает так, как вы ожидаете, заключается в следующем:
Приложение Windows Forms использует отдельный поток пользовательского интерфейса, который постоянно обрабатывает входящие сообщения из очереди.Любые обработчики событий, которые вы присоединяете к событиям элемента управления Windows Forms, отправляются в эту очередь и обрабатываются потоком пользовательского интерфейса как можно быстрее.
Ваш btnCompleteAuto_Click
является одним из таких обработчиков.Как только он запускается, ничего больше не будет обрабатываться потоком пользовательского интерфейса, пока он не выйдет из .Таким образом, любые другие обработчики , которые вы присоединяете к другим событиям (btnPause_Click
, btnStop_Click
и т. Д.), Должны ждать своей очереди, поскольку они будут выполняться в том же потоке (UI).
Если вы хотите, чтобы функция паузы / возобновления работала, это имеет , которая должна быть достигнута в отдельном потоке.
Возможный способ реализовать это - использовать BackgroundWorker
, как предложено saurabh .
Вот грубый набросок того, как может выглядеть ваш обновленный код (я даже не пытался компилировать это, не говоря уже об отладке; оно предназначено только как базовая схема того, как вы можете выполнить эту функцию).
Однако вы должны знать, что доступ к элементам управления UI напрямую из потока, не являющегося UI,нет-нет.Используйте механизм, такой как событие BackgroundWorker.ProgressChanged
, для обработки любых обновлений пользовательского интерфейса, которые должны произойти на основе активности в потоке без пользовательского интерфейса.
ManualResetEvent _busy = new ManualResetEvent(false);
private void btnCompleteAuto_Click(object sender, EventArgs e)
{
if (!backgroundWorker.IsBusy)
{
_busy.Set();
btnAutoCompleteAuto.Text = "Pause";
backgroundWorker.RunWorkerAsync();
}
else
{
_busy.Reset();
btnAutoCompleteAuto.Text = "Resume";
}
btnStop.Enabled = true;
}
private void btnStop_Click(object sender, EventArgs e)
{
_busy.Set();
backgroundWorker.CancelAsync();
}
private void backgroundWorker_DoWork(object sender, DoWorkEventArgs e)
{
// for (something)
// {
_busy.WaitOne();
if (backgroundWorker.CancellationPending)
{
return;
}
// Do your work here.
// }
}
private void backgroundWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
_busy.Reset();
btnAutoCompleteAuto.Text = "Start";
btnStop.Enabled = false;
}