2015-07-19 162 views
2

我想打一個窗體應用程序更新的textBox文本每0.1秒 所以我這樣做:如何運行while循環?

private void Start_Stop_Click(object sender, EventArgs e) 
{ 
    double x; 
    while (true) 
    { 
     x = x + 0.00522222222222222222222222222222; 
     y.Text = x.ToString(); 
     Thread.Sleep(100); 
    } 
} 

,但是當我跑的程序,它只是凍結
(我寫的幾乎確切在控制檯應用程序中運行,並且運行平穩)。

+3

在另一個線程執行的方法,或者使用'Timer' –

+0

我tryed使用另一個線程,但它給了我一些其他錯誤,但我該如何使用計時器? – ronald7894

+0

@ ronald7894它不僅是關於使用其他線程,但你應該能夠從該線程調用你的UI線程的變化。這裏可能的解決方案之一是使用同步上下文。這是在我的回答... – Fabjan

回答

3

雖然沒有多大意義,但您可以使用Task.Delay來實現您想要的效果。它會產生異步控制回UI消息循環(在內部,它採用的是定時器):

private bool shouldIterate; 
private async void StartStopClick(object sender, EventArgs e) 
{ 
    if (shouldIterate) 
    { 
     shouldIterate = false; 
     return; 
    } 

    shouldIterate = true; 
    while (shouldIterate) 
    { 
     x = x + 0.00522222222222222222222222222222; 
     y.Text = x.ToString(); 
     await Task.Delay(100); 
    } 
} 

雖然我建議您將時間間隔設置爲更合理。

+0

tnx男人它的工作,我還有另一個問題,如何在另一個點擊該按鈕,我可以打破該循環? – ronald7894

+0

在這個解決方案中,我必須製作另一個按鈕,是否有可能無需額外的按鈕? – ronald7894

+0

@ronald您要如何取消它?經過一定的時間間隔? –

5

使用Timer這樣的:

double x = 0; 
Timer timer1 = new Timer(); 

public Form1() 
{ 
    InitializeComponent(); 
    timer1.Interval = 100; 
    timer1.Tick += new EventHandler(timer1_Tick); 
} 

private void Start_Stop_Click(object sender, EventArgs e) 
{ 
    if (timer1.Enabled) 
    { 
     timer1.Stop(); 
    } 
    else 
    { 
     timer1.Start(); 
    } 
} 
private void timer1_Tick(object sender, EventArgs e) 
{ 
    x = x + 0.00522222222222222222222222222222; 
    textBox1.Text = x.ToString(); 
} 
+0

@OldFox接受的答案最初也沒有回答。在這裏也可以很容易地將邏輯與布爾標誌和定時器啓動/停止一起使用。這只是初學者更容易理解的答案。我清楚地懷疑他理解了他接受的答案中的異步部分。 – msmolcic

+0

@msmolcic我同意你的觀點,YuvalItzchakov沒有解釋他的答案,我不喜歡它。看看我寫給OP使用'Timer'的問題的評論,我的電腦不是windows,我明白OP是初學者,我不想把他與輸入錯誤混淆...... user2946329'Timer'具有名爲「Enabled」的屬性,您不需要添加任何其他字段。更新你的答案,然後我會投票了.... –

0

您也可以運行一個單獨的任務傳遞一個同步上下文。使用volatile關鍵字來確保您的isCanceled字段可以以不同線程的線程安全方式使用。你可以用它作爲'while'循環的條件(開始/停止你的任務)。

volatile bool isCanceled = true; 

    private void Start_Stop_Click(object sender, EventArgs e) 
    {    
     isCanceled = !isCanceled; 
     if(isCanceled) return; 

     // gets context of current UI thread (to update smth later using it) 
     SynchronizationContext cont = SynchronizationContext.Current; 

     // starts hot task with your logic 
     Task.Factory.StartNew(() => 
     {         
      double x = 0; 
      while (!isCanceled) 
      { 
       x = x + 0.05; 

       // this operation will be executed on UI thread with use of sync context 
       cont.Post(delegate { y.Text = x.ToString(); }, null);     

       Thread.Sleep(100); 
      } 
     }); 
    }