Стоп цикл в классе из другого класса - PullRequest
0 голосов
/ 20 августа 2011

Итак, у меня есть два обработчика событий button1_Click () и button2_Click ()

В button1_Click () у меня что-то работает так:

toGet = textbox1.Text;
got = 0;

while (got <= toGet)
{
  //DoStuff
}

Но button2_Click должен быть остановкойКнопка и остановка button1 рано.Как мне это сделать?Спасибо за помощь.Я видел эту статью здесь об этом, но не смог заставить ее работать.

Ответы [ 3 ]

1 голос
/ 20 августа 2011

Ответ Windows.Forms

Наименее сложный метод заключается в следующем:

private bool m_stop;
private void button1_Click (object s, EventArgs ea)
{
   try
   {
   //  Don't forget to disable all controls except the ones you want a user to be able to click while your method executes.

      toGet = textbox1.Text;
      got = 0;

      while (got <= toGet)
      {
        Application.DoEvents (); 
        // DoEvents lets other events fire.  When they are done, resume.
        if (m_stop)
           break;
        //DoStuff
      }

   finally
   {
      //  Enable the controls you disabled before.
   }
}

private void button2_Click (object s, EventArgs ea)
{
   m_stop = true;
}

Он имеет явное преимущество, позволяя вам выполнять button1_Click в потоке пользовательского интерфейса,все еще позволяет интерфейсу реагировать на вашу кнопку остановки.

У него есть недостаток, который вы должны защитить от повторного входа.Что произойдет, если они нажмут на кнопку button1, когда button1_click уже выполняет!?!?

Редактировать: Другой способ, который я использовал, - использовать таймер вместо цикла.Затем метод stop просто останавливает таймер.

0 голосов
/ 20 августа 2011

Вам нужно запустить процесс внутри button1 в новом потоке, а когда вы нажимаете button2, помечаете локальную переменную как false, чтобы остановить цикл.как:

using System.Threading;

private volatile bool _requestStop = false;
private readonly object _oneExecuteLocker = new object();    


private void OnButton1Click(ojbect sender, EventArgs e)
{
    new Thread(() =>
    {
        if (Monitor.TryEnter(_oneExecuteLocker))
        {//if we are here that is means the code is not already running..
            try
            {
                while (!_requestStop)
                {
                    //DoStuff
                } 
            }
            finally
            {
                Monitor.Exit(_oneExecuteLocker);
            }
        }
    }){ IsBackground = true }.Start();
}

private void OnButton2Click(object sender, EventArgs e)
{
    _requestStop = true;
}

Примечания:

  • Если вы хотите обновить элемент управления пользовательского интерфейса во вновь созданном потоке, вы должны использовать contorl.Invoke(/*the code get/set or call method in the UI*/).
  • Monitro.Enter просто для того, чтобы убедиться, что ваш код не будет выполняться несколько раз за клик, если он уже запущен.
0 голосов
/ 20 августа 2011

Насколько я понял, поправьте меня, если я ошибаюсь, вы на одной ветке.Проводной, но вы можете проверить наличие единственного логического значения в цикле while, как предложено в посте.

Может быть, чтобы упростить жизнь (возможно, это то, что означает "не удалось заставить его работать")внутри вызова цикла

1) Windows Forms: Application.DoEvents()

2) WPF (немного сложнее): DoEvents в WPF

Thisзаставить дышать систему.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...