2012-06-09 253 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'。也許有常數,例如:'開始','已暫停','停止'。這樣,只能有一個狀態,你不必記住哪些其他變量來改變狀態。 –

+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

你是對的布爾條件,謝謝。我把它清理了一下 –