Thread: Display counts on textBox

  1. #1
    Registered User
    Join Date
    Nov 2009
    Posts
    53

    Display counts on textBox

    Hello,

    I have a very simple application that I want to display counts on a textbox. The problem is that the counter freezes the entire program and it only shows the last count. So I want to count from 0 to 100 incrementally with a delay of 250ms per count and display as it counts on the text box. 0...1...2...3......100 etc

    Code:
            private void count()
            {
    
                for (int i = 0; i < 101; i++)
                {
    
                    textBox3.Text = i.ToString();
                    Thread.Sleep(50);
    
                }
                    
            }

  2. #2
    Registered User
    Join Date
    May 2003
    Posts
    1,619
    To understand why this happens (and how to prevent this from happening), fundamentally WinForms are single-threaded. That is, while count() is happening, no other part of the program is executing - including the message pump that is responsible for handling any new events including responding to input and redrawing controls.

    One answer would be to multithread the program - putting the busy work in the background - but you do need to be very careful about how you update the GUI in the worker thread (the C# built in BackgroundWorker class can help simplify this).

    For this specific code, though, where the thread spends nearly all its time sleeping, the better answer would be to create a timer, add an event handler to the timer, and return control to the message pump. So your tick event handler would basically just update the number and immediately quit; the next time the timer event occurs, the message pump will call your handler again.

    Good rules of thumb:

    1. Anything that happens in your main thread (e.g. event handlers) should finish in no more than two seconds. Anything taking longer needs to happen in the background, or be redesigned.

    2. Thread.Sleep() should be used very sparingly. Much better are use of timers or other callback mechanisms that can raise an event when something of interest happens. It should virtually never be used in your main thread; even in worker threads, it's usually better to block until an event rather than block for a length of time.
    You ever try a pink golf ball, Wally? Why, the wind shear on a pink ball alone can take the head clean off a 90 pound midget at 300 yards.

  3. #3
    Registered User cstryx's Avatar
    Join Date
    Jan 2013
    Location
    Canada
    Posts
    123
    If that's the way you've chosen then you need to rethink your application design. Thread.Sleep() in the way you're using it is very very poor design, and it should never be used like that. You should be using a Timer. If you were to keep Thread.Sleep() though in this way, the only way this would work is if you started this on a new thread, and when updating the TextBox, which was probably added via the designer in the Visual Studio IDE, you will have to Invoke() from the separate thread back to the main UI thread in order to change that Text property.

    This, what you have there, is a good example of what you should not be doing though, regardless. So use a Timer.

  4. #4
    Registered User
    Join Date
    Nov 2009
    Posts
    53
    Thanks guys, I now understand what you mean. At this point I'm trying to implement a timer of 1 sec that would output the alphabet, instead of a count, to the text box. This is for a loopback test of a RS422 line. So far it works, but not as I expected.

    Code:
    private void timer1_Tick(object sender, EventArgs e)
            {   
                string _sTX_out = "A";
                string _sRX_count;
                _sPort.Open();
                //for (int i = 0; i < 2; i++)
                //{
    
                    _sPort.WriteLine(_sTX_out);
                        _sRX_count = _sPort.ReadLine() + 1;
                        textBox3.Text = _sRX_count;
    
                //}
                _sPort.Close(); 
            }

  5. #5
    Registered User cstryx's Avatar
    Join Date
    Jan 2013
    Location
    Canada
    Posts
    123
    Quote Originally Posted by drkidd22 View Post
    Thanks guys, I now understand what you mean. At this point I'm trying to implement a timer of 1 sec that would output the alphabet, instead of a count, to the text box. This is for a loopback test of a RS422 line. So far it works, but not as I expected.

    Code:
    private void timer1_Tick(object sender, EventArgs e)
            {   
                string _sTX_out = "A";
                string _sRX_count;
                _sPort.Open();
                //for (int i = 0; i < 2; i++)
                //{
    
                    _sPort.WriteLine(_sTX_out);
                        _sRX_count = _sPort.ReadLine() + 1;
                        textBox3.Text = _sRX_count;
    
                //}
                _sPort.Close(); 
            }
    So for serial COM port A, if that doesn't change then why have it re-declared each time? Just define it as a const string outside of the timer event method. You shoulnd't need a variable for _sRX_count, and prefixing variables with a "_" is usually a standard to indicate a field, in which these local variables are not. Also, the return value for ReadLine() is a string, why are you adding an integer to it?
    Code:
    _sPort.ReadLine() + 1;
    And why not:
    Code:
    textBox3.Text = _sPort.ReadLine();
    Eliminate the _sRX_count variable, and don't mix data types like that.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 13
    Last Post: 05-02-2012, 04:17 PM
  2. words counts
    By lingz82 in forum C++ Programming
    Replies: 3
    Last Post: 08-31-2006, 05:16 AM
  3. I Guess This Counts As A Game....
    By Krak in forum Game Programming
    Replies: 12
    Last Post: 07-07-2003, 08:57 PM
  4. post counts...
    By ober in forum A Brief History of Cprogramming.com
    Replies: 15
    Last Post: 02-04-2002, 09:50 PM