2012-06-09 4 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)'로 충분하지 않습니다. 그리고 다음과 같이 "paused"라고 이름을 짓고 앞면에 "is"를 추가 할 수 있습니다. 여전히 의미가 있습니다. 이 코드는 약간의 깔끔함이 필요합니다. showwaiting 호출을 제어하기 위해 이벤트 사용을 고려해야합니다. –

+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 상태에 대해 감사합니다. 나는 그것을 조금 청소했다. –