2015-07-19 163 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); 
      } 
     }); 
    }