2014-02-19 60 views
1

我正在檢查是否可以在單擊按鈕時在文本框中顯示計時器。點擊按鈕時,定時器應該開始運行,並且在完成過程之後,我想停止定時器。以下是我的。我應該怎樣才能使它工作?窗口計時器在文本框中

public partial class MyClass: Form 

{ 
public MyClass() 
{ 
    InitializeComponent(); 
    InitializeTimer();  
} 

private void InitializeTimer() 
{ 
    this.timer1.Interval = 1000; 
    this.timer1.Tick += new EventHandler(timer1_Tick); 
    // don't start timer until user clicks Start    
} 

private void timer1_Tick(object sender, EventArgs e) 
{ 
    processingMessageTextBox.Invoke(new MethodInvoker(delegate { processingMessageTextBox.Text = "show running time after click"; })); 
}  

private void myButton_Click(object sender, EventArgs e) 
{ 
    this.timer1.Start();  
    doSomeTimeCOnsumingWork(); 
    this.timer1.Stop();  

}   

}

請建議。

+1

什麼不起作用? – LokiSinclair

+0

您能否提供有關過程的更多信息,以及您想要在文本框中顯示的內容?到目前爲止,您的代碼看起來是有效的,但所有會發生的是每個計時器滴答,文本框文本將被替換爲相同的字符串。 –

+0

另外,您正在GUI線程上調用doSomeTimeConsumingWork(),這將導致GUI在doSomeTimeConsumingWork()返回之前變得無響應。由timer1_Tick方法排隊的調用將在myButton_Click方法後面等待。你應該調查BackgroundWorker類。 –

回答

1

我會用另一個Thread(或BackgroundWorker)更新TextBox(或Label)隨着時間的流逝,直到工作完成。

而且我也會使用Stopwatch而不是Timer(更容易獲得流逝的時間)。

代碼如下;

首先,添加該字段:

private Stopwatch sw = new Stopwatch(); 

現在,添加一個BackgroundWorker更新的時間。 在BackgroundWorkerDoWork事件中,有這樣的代碼,以保持更新相應TextBoxLabel與經過時間:

private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e) 
{ 
    while (sw.IsRunning) 
    { 
     // Display elapsed time in seconds. 
     processingMessageTextBox.Invoke(new MethodInvoker(delegate { processingMessageTextBox.Text = (sw.ElapsedMilliseconds/1000).ToString(); })); 
    } 
} 

確保您doSomeTimeCOnsumingWork運行的另一個線程,這樣你就不會阻止UI。

您可以使用另一BackgroundWorker爲此目的或僅使用Thread類。

在你doSomeTimeCOnsumingWork(你可以創建另一個BackgroundWorker的它)增加以下內容:

private void doSomeTimeCOnsumingWork() 
{ 
    sw.Reset(); 
    sw.Start(); 

    // Some work done here 

    sw.Stop(); 
} 
1

有幾十個錯誤methink。

MyClass不是表單的正確名稱。

無需Invoke在計時器事件(因爲它在UI線程創建的),根本就事件

private void timer1_Tick(object sender, EventArgs e) 
{ 
    processingMessageLabel.Text = "show running time after click"; 
} 

myButton_Click事件一次執行所有的工作,阻塞UI線程,使其更喜歡這個(切換timer1

private void myButton_Click(object sender, EventArgs e) 
{ 
    timer1.Enabled = !timer1.Enabled; 
} 

什麼?你想要執行doSomeTimeConsumingWork?你爲什麼不使用ThreadTaskBackgroundWorker這個?

+0

「MyClass」是不是正確的名稱?他可以任何他想要的名字命名他的「形式」類。 –

+0

MyClass不是實際的名稱。我用一個不同的類名粘貼了一部分代碼。 – San

1

您對doSomeTimeConsumingWork()的調用發生在GUI線程中。 Windows窗體是單線程的 - 這意味着定時器將不會被服務,直到doSomeTimeConsumingWork()返回。此外,正如另一個答案所提到的,沒有必要在Windows窗體計時器上使用Invoke,因爲它已經在GUI線程上。

調查System.Windows.Forms.BackgroundWorker類,將耗時的工作放在單獨的線程上。 BackgroundWorker包括一個報告進度的機制。見this MSDN article

相關問題