ronald7894
ronald7894

Reputation: 67

How to run a while loop?

I want to make a forms application that update the text in a textBox every 0.1 sec so I did that:

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

but when I ran the program, it just froze
(I wrote almost the exact program in a console application and it ran smoothly).

Upvotes: 2

Views: 160

Answers (3)

Salah Akbari
Salah Akbari

Reputation: 39956

Use Timer like this:

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();
}

Upvotes: 5

Fabjan
Fabjan

Reputation: 13676

You can also run a separate task passing it a synchronization context. Use volatile keyword to make sure that your isCanceled field can be used in a thread-safe way from different thread. You can use it as condition for your 'while' loop (to start/stop your task).

   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);
             }
        });
    }

Upvotes: 0

Yuval Itzchakov
Yuval Itzchakov

Reputation: 149538

Although not making much sense, You can achieve what you want using Task.Delay. It will asynchronously yield control back to the UI message loop (internally, it uses a timer):

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);
    }
}

Although I suggest you set your interval to something more reasonable.

Upvotes: 3

Related Questions