2012-06-09 3 views
0

У меня есть следующий код, который работает, но он очень грязный. На самом деле код очень хорош, кроме той части, которую я добавил: пауза и кнопка остановки. Я новичок в C#, поэтому любая помощь будет оценена.приостановка и остановка нитей

private void pause_button_Click(object sender, EventArgs e) 
    { 
     start = false; pause = true; stop = false; 
     guiUpdate(); 
     PauseEvent.Reset(); 
    } 

    private void stop_button_Click(object sender, EventArgs e) 
    { 
     if (pause == true) 
     { 
      PauseEvent.Set(); 
      pause = false; 
      this.start_button.Click -= new System.EventHandler(this.resume_button_Click); 
     } 
     start = false; stop = true; 
    } 

    private int activeThreads = 0; 
    private Thread thread; 
    private void DoWork(object sender) 
    { 
     string line = null; 
     ereader = new StreamReader(MY_LIST); 
     do 
     { 
      lock (ereader) 
      { 
       PauseEvent.WaitOne(); 
       line = ereader.ReadLine(); 
      } 

      // 
      //other commands for processing & building the argument 
      // 

      lock (signal) 
      { 
       ++activeThreads; 
      } 

      thread = new Thread(new ParameterizedThreadStart(
       o => 
       { 
        processit((object)o); 
        lock (signal) 
        { 
         --activeThreads; 
         Monitor.Pulse(signal); 
        } 
       })); 
      thread.Start(argument); 

      lock (signal) 
      { 
       while (activeThreads > maxthreads) 
        Monitor.Wait(signal); 
      } 

      lock (signal) 
      { 
       if (!start) 
       { 
        showwaiting(true);//shows an animated gif with a "please wait" msg 
        while (activeThreads > 0) 
         Monitor.Wait(signal); 
        showwaiting(false); 
        if (stop == true) 
        { 
         this._BackgroundWorker.CancelAsync(); 
         break; 
        } 
       } 
      } 
     } 
     while (ereader.Peek() != -1); 
     showwaiting(true); 
     lock (signal) 
     { 
      while (activeThreads > 0) 
       Monitor.Wait(signal); 
     } 
     showwaiting(false); 
    } 


    private void _BackgroundWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) 
    { 
     start = false; stop = true; 
     guiUpdate(); 
    } 

, что именно я могу сделать, чтобы избежать этих повторяющихся команд внутри и вне цикла?

+0

Не использовать 'if (pause == true)', 'if (pause)' будет достаточно, плюс я бы назвал его «приостановленным», поскольку он следует за ним, вы можете добавить «is» на передней панели и это все равно имеет смысл. Этот код требует немного аккуратного. Вы должны рассмотреть возможность использования событий для управления вызовами, ожидающими вызова. –

+0

Кроме того, я думаю, что я изменил бы все эти переменные 'bool' на один« enum ». Возможно, с константами, такими как: 'Start',' Paused', 'Stop'. Таким образом, может быть только одно состояние, и вам не нужно помнить, какие другие переменные изменяют состояние. –

+0

спасибо, но знаете ли вы, как избавиться от этого повторяющегося цикла activethreads? –

ответ

1

Упомянутые в вопросе комментарии - это предложения по изменению практики кода.

  • Не используйте == true или == false при проверке булеву переменную в состоянии. (Jeff)
  • Используйте перечисление для представления состояния вместо нескольких булевых переменных.

Я хотел бы также добавить:

  • Используйте правильный C# соглашения об именовании. Для ваших методов, если есть несколько слов, используйте все слова. (например, вместо showwaiting использовать ShowWaiting).

Для небольших петель вам не нужно оптимизировать их, хотя существует более простой цикл. Таким образом, вы можете реорганизовать их в отдельный метод вместе со всем кодом, который является тем же самым:

private void ShowAndWait() 
{ 
    showwaiting(true); 
    lock (signal) 
    { 
     while (activeThreads > 0) 
      Monitor.Wait(signal); 
    } 
    showwaiting(false); 
} 

Обратите внимание, что это нормально для той же нити, чтобы зафиксировать на экране монитора, что он ранее приобрел. Это быстрая операция, так как поток уже владеет блокировкой. Затем вы можете вызвать этот метод из обоих мест.

+0

Вы правы насчет состояния bool, спасибо. Я немного почистил его –

Смежные вопросы