2012-04-26 67 views
1

說明:更新Windows窗體 - C#

結構:Windows窗體 - 三個組件:文本框,文本框響應和按鈕。

問題:我正在用C#windows窗體移動電機:我正在啓動電機,並在中間以10秒的延遲時間單向按鈕單擊電機的運動方向
。即我啓動電機,有10秒延遲,然後使電機反轉。我想在開始時顯示「開始」,在10秒延遲結束時顯示「結束」。我曾嘗試使用線程,但它不起作用。但我只能在文本框中看到「完成」而不是「開始」。代碼如下:

using System; 
using System.Collections.Generic; 
using System.ComponentModel; 
using System.Data; 
using System.Drawing; 
using System.Linq; 
using System.Text; 
using System.Windows.Forms; 
using System.Threading; 

namespace SampleThreadProgram 
{ 
    public partial class Form1 : Form 
    { 
      static EventWaitHandle _waitHandle = new AutoResetEvent(false); 
      delegate void SetTextCallback(string text); 

    void SetText(string text) 
    { 
      if (textBox.InvokeRequired) 
      { 
      SetTextCallback d = new SetTextCallback(SetText); 
      BeginInvoke(d, new object[] { text }); 
      } 
      else 
      { 
      textBox.Text = text; 
      } 
    } 

    void UpdateTextBox(string message) 
    { 
     SetText(message); 
     _waitHandle.Set(); 
    } 

    void Wait() 
    { 
     for (ulong i = 0; i < 10000; i++) 
     { 
      for (ulong j = 0; j < 100000; j++) 
      { 
      } 
     } 

    } 
    public Form1() 
    { 
     InitializeComponent(); 
    } 

    private void Form1_Load(object sender, EventArgs e) 
    { 

    } 

    private void button1_Click(object sender, EventArgs e) 
    { 

     UpdateTextBox("Start"); 
     _waitHandle.WaitOne(); 
     Thread.Sleep(10000); 
     UpdateTextBox("Finish"); 

    } 

    } 
} 

回答

0

沒有足夠的時間讓UI更新。在SetText(message);UpdateTextBox之後添加Application.DoEvents();

+0

Servy的答案更多地解決了代碼問題,而不僅僅是回答提出的問題,就像我的答案一樣。 – zimdanen 2012-04-26 18:33:45

4
  1. 您不應該使用大的長for循環使計算機等待一段時間。至少使用Thread.Sleep
  2. 你應該使用BackgroundWorker來做你想做的事情。在按鈕單擊事件中設置開始文本,然後啓動後臺工作程序。您可以讓事件DoWork做一些工作(在這種情況下爲睡眠)並使用WorkerCompleted事件來更新UI。

使用後臺工作器的好處是您不必擔心更新非UI線程的代碼形式。在按鈕單擊事件中,您可以直接更新文本框的文本,並且BackGroundWorker線程已經確保Completed事件在UI線程中運行,所以即使在那裏您也可以直接訪問UI控件。 BGW專門設計用於使這個確切的案例更容易。