Click here to Skip to main content
15,891,184 members
Please Sign up or sign in to vote.
1.00/5 (1 vote)
See more:
Hi,
I want to display some calculated values continuously in two text boxes in my C# windows application. This execution should be done simultaneously means both text boxes should update at the same time but not one after one. I using Visual Studio 2008.

Please help me.... I am totally new to this.

Thanks.

What I have tried:

I am trying this using threading, but as i am using Thread.Sleep(1000), updation at second text box starts after 1 second. It is necessary to use Sleep() to read values in the text box. Please suggest alternate method to Sleep() so that user can read values in text box & also second thread will not be block.
Posted
Updated 30-Nov-16 21:52pm
Comments
Ralf Meier 1-Dec-16 3:55am    
I think that the solution of CPallini doesn't match to your question - but I'm not sure.
Please explain once more, with some code which Shows what you have coded until now, what you try to achieve.
Controls (like Textboxes) belong to the main-Thread and could not directly accessed through a sub-Thread. For this you should use he Invoke-Method of the Controls which tells them that there is something to do when the main-Thread has got back the control.
If you write Sleep(0) inside your Thread you allow the Main-Thread for a short moment to do necessary actions.
virus131 1-Dec-16 5:40am    
Actually i tried this by using Invoke as well as BeginInvoke method. but its not working properly.
Ralf Meier 1-Dec-16 6:38am    
... then show your code (improve your question with the code-snippet)

Quote:
This execution should be done simultaneously means both text boxes should update at the same time

That's impossible, you know.
However if you write, for instance
C#
textbox1.Text = "foo";
textbox2.Text = "boo";
// .. some delay here

The user would perceive it as a simultaneus update.
 
Share this answer
 
A C# Windows application? Presume you mean a legacy Windows Forms application then, i've taken the trouble to make an example explaining the concept. Basically you need to get your calculations away from the UI Thread, but remember to get the updates to your UI controls executed on it.
I've taken the liberty to use listboxes instead of textboxes, as textboxes are just silly to display running values in IMO, feel free to change that though if there is some compelling reason :)

So standard form with two listboxes in the leftmost part, a start and a stop button and a label indicating if the applications is running. I use a Random object to sleep the updates a different random period between 100-2000 milliseconds to imitate calculations.
using a timer is very common to ensure recurring events, when using such it has its own thread and care must be taken not to execute multiple occurances simultaneously (like when executing the occurance of the timed event takes longer than the time between event occurances.)

UPDATE: Now added and using numbers, as requester had that wish

Code behind:
C#
using System;
using System.Threading;

using System.Windows.Forms;

namespace FormThings
{
    public partial class TheForm : Form
    {
        private static Random Rnd { get; set; }

        private delegate void ListboxUpdateDelegate(ListBox listbox);
        public TheForm()
        {
            InitializeComponent();
            Rnd = new Random((int)DateTime.Now.Ticks);
        }

        private volatile int _countOne = 0;
        private volatile int _countTwo = 0;

        private void TimeX_Tick(object sender, EventArgs e)
        {
            if (_timeExecuting)
                return;
            try
            {
                _timeExecuting = true;

                int seedOne = Rnd.Next(100, 2000);
                int seedTwo = Rnd.Next(100, 2000);

                //var t1 = Task.Factory.StartNew((seed) => { UpdateControl(FirstListBox, (int)seed); },seedOne);
                //var t2 = Task.Factory.StartNew((seed) => { UpdateControl(SecondListBox, (int)seed); }, seedTwo);

                //Use below if you're compiling aganst older version of framework than 4.5
                var state1 = new V35CompatibleContainer
                {
                    ListBox = FirstListBox,
                    Seed = seedOne,
                };
                ThreadPool.QueueUserWorkItem(ExcecuteV35compatibleOnThreadPool, state1);
                var state2 = new V35CompatibleContainer
                {
                    ListBox = SecondListBox,
                    Seed = seedTwo,
                };
                ThreadPool.QueueUserWorkItem(ExcecuteV35compatibleOnThreadPool, state2);


            }
            catch (Exception ex)
            {
                System.Diagnostics.Debug.WriteLine("Exception in time tick event: " + ex.ToString());
            }
            finally
            {
                _timeExecuting = false;
            }
        }
        private volatile bool _timeExecuting = false;

        private void ExcecuteV35compatibleOnThreadPool(object state)
        {
            var stateContainer = (V35CompatibleContainer)state;
            UpdateControl(stateContainer.ListBox, stateContainer.Seed);
        }
        private class V35CompatibleContainer
        {
            public ListBox ListBox;
            public int Seed;
        }

        private void UpdateControl(ListBox listBox, int seed)
        {
            System.Threading.Thread.Sleep(seed);
            if (listBox.InvokeRequired)
            {
                listBox.BeginInvoke(new ListboxUpdateDelegate(InsertIncrementLoop), new object[] { listBox });
                return;
            }
            InsertIncrementLoop(listBox);
        }

        private void InsertMoment(ListBox listBox)
        {
            listBox.Items.Insert(0, DateTime.Now.ToString("HH:mm:ss.fff"));
        }

        private void InsertIncrementLoop(ListBox listBox)
        {
            int theValueNumber = -1;
            if (listBox.Name == "FirstListBox")
            {
                theValueNumber = Interlocked.Increment(ref _countOne);
                if (theValueNumber == 10)
                    Interlocked.Exchange(ref _countOne, 0);
            }
            else
            {
                theValueNumber = Interlocked.Increment(ref _countTwo);
                if (theValueNumber == 10)
                    Interlocked.Exchange(ref _countTwo, 0);
            }
            listBox.Items.Insert(0, theValueNumber.ToString());
        }

        private void ToggleRunmode()
        {
            StopButton.Enabled = !StopButton.Enabled;
            StartButton.Enabled = !StopButton.Enabled;
            if (StopButton.Enabled)
            {
                FirstListBox.Items.Clear();
                SecondListBox.Items.Clear();
            }
            TimeX.Enabled = StopButton.Enabled;
            RunningLabel.Visible = StopButton.Enabled;
        }

        private void StartButton_Click(object sender, EventArgs e)
        {
            ToggleRunmode();
        }

        private void StopButton_Click(object sender, EventArgs e)
        {
            ToggleRunmode();
        }

        private void TheForm_Load(object sender, EventArgs e)
        {

        }
    }
}



Designer:
C#
namespace FormThings
{
    partial class TheForm
    {
        /// <summary>
        /// Required designer variable.
        /// </summary>
        private System.ComponentModel.IContainer components = null;

        /// <summary>
        /// Clean up any resources being used.
        /// </summary>
        /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
        protected override void Dispose(bool disposing)
        {
            if (disposing && (components != null))
            {
                components.Dispose();
            }
            base.Dispose(disposing);
        }

        #region Windows Form Designer generated code

        /// <summary>
        /// Required method for Designer support - do not modify
        /// the contents of this method with the code editor.
        /// </summary>
        private void InitializeComponent()
        {
            this.components = new System.ComponentModel.Container();
            this.StartButton = new System.Windows.Forms.Button();
            this.StopButton = new System.Windows.Forms.Button();
            this.FirstListBox = new System.Windows.Forms.ListBox();
            this.SecondListBox = new System.Windows.Forms.ListBox();
            this.RunningLabel = new System.Windows.Forms.Label();
            this.TimeX = new System.Windows.Forms.Timer(this.components);
            this.SuspendLayout();
            // 
            // StartButton
            // 
            this.StartButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
            this.StartButton.Location = new System.Drawing.Point(337, 13);
            this.StartButton.Name = "StartButton";
            this.StartButton.Size = new System.Drawing.Size(75, 38);
            this.StartButton.TabIndex = 0;
            this.StartButton.Text = "&Start";
            this.StartButton.UseVisualStyleBackColor = true;
            this.StartButton.Click += new System.EventHandler(this.StartButton_Click);
            // 
            // StopButton
            // 
            this.StopButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
            this.StopButton.Enabled = false;
            this.StopButton.Location = new System.Drawing.Point(337, 57);
            this.StopButton.Name = "StopButton";
            this.StopButton.Size = new System.Drawing.Size(75, 38);
            this.StopButton.TabIndex = 1;
            this.StopButton.Text = "S&top";
            this.StopButton.UseVisualStyleBackColor = true;
            this.StopButton.Click += new System.EventHandler(this.StopButton_Click);
            // 
            // FirstListBox
            // 
            this.FirstListBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) 
            | System.Windows.Forms.AnchorStyles.Left)));
            this.FirstListBox.FormattingEnabled = true;
            this.FirstListBox.Location = new System.Drawing.Point(13, 13);
            this.FirstListBox.Name = "FirstListBox";
            this.FirstListBox.Size = new System.Drawing.Size(122, 173);
            this.FirstListBox.TabIndex = 2;
            // 
            // SecondListBox
            // 
            this.SecondListBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) 
            | System.Windows.Forms.AnchorStyles.Right)));
            this.SecondListBox.FormattingEnabled = true;
            this.SecondListBox.Location = new System.Drawing.Point(141, 12);
            this.SecondListBox.Name = "SecondListBox";
            this.SecondListBox.Size = new System.Drawing.Size(122, 173);
            this.SecondListBox.TabIndex = 3;
            // 
            // RunningLabel
            // 
            this.RunningLabel.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
            this.RunningLabel.AutoSize = true;
            this.RunningLabel.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(0)))), ((int)(((byte)(192)))), ((int)(((byte)(0)))));
            this.RunningLabel.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
            this.RunningLabel.ForeColor = System.Drawing.Color.White;
            this.RunningLabel.Location = new System.Drawing.Point(320, 130);
            this.RunningLabel.Name = "RunningLabel";
            this.RunningLabel.Size = new System.Drawing.Size(92, 20);
            this.RunningLabel.TabIndex = 4;
            this.RunningLabel.Text = "RUNNING !";
            this.RunningLabel.Visible = false;
            // 
            // TimeX
            // 
            this.TimeX.Interval = 250;
            this.TimeX.Tick += new System.EventHandler(this.TimeX_Tick);
            // 
            // TheForm
            // 
            this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
            this.ClientSize = new System.Drawing.Size(424, 205);
            this.Controls.Add(this.RunningLabel);
            this.Controls.Add(this.SecondListBox);
            this.Controls.Add(this.FirstListBox);
            this.Controls.Add(this.StopButton);
            this.Controls.Add(this.StartButton);
            this.MinimumSize = new System.Drawing.Size(440, 244);
            this.Name = "TheForm";
            this.Text = "TheForm - A legacy windows application";
            this.ResumeLayout(false);
            this.PerformLayout();

        }

        #endregion

        private System.Windows.Forms.Button StartButton;
        private System.Windows.Forms.Button StopButton;
        private System.Windows.Forms.ListBox FirstListBox;
        private System.Windows.Forms.ListBox SecondListBox;
        private System.Windows.Forms.Label RunningLabel;
        private System.Windows.Forms.Timer TimeX;
    }
}
 
Share this answer
 
v4
Comments
virus131 1-Dec-16 5:44am    
hi.. thanks for reply.. but i am using C# 3.5
Thomas Nielsen - getCore 1-Dec-16 6:00am    
Just updated solution for the 3.5 edition.
virus131 2-Dec-16 23:33pm    
Hi Thomas Nielsen, Thank you very much for your solution. Its absolutely working fine with textbox also. But what if I am using below code (in InsertMoment()) instead of displaying date time in my textbox-

private void InsertMoment(TextBox textBox)
{
//textBox.Text = DateTime.Now.ToString("HH:mm:ss.fff");
for (int i = 0; i < 10; i++)
{
textBox.Text = i.ToString();
}
}

this does not showing proper output means 0-9 values in textbox.

Again i changed my code to see updating 0-9 in text box as -

private void InsertMoment(TextBox textBox)
{
//textBox.Text = DateTime.Now.ToString("HH:mm:ss.fff");
for (int i = 0; i < 10; i++)
{
textBox.Text = i.ToString();
Thread.Sleep(100);
textBox.Refresh();
}
}

This shows updating values in textbox but one after one, means this does not update both text box simultaneously. I dont know whether it is possible or not.
And if it is possible then what to do to achieve this.
Thomas Nielsen - getCore 6-Dec-16 7:58am    
What you're doing is when the execution gets focus so to say, you then make a rapid loop updating each of the values, which it's reach from say 0 to 10 in only a few milliseconds. Hence human eye won't see.
Your second attempt then is to refresh the textbox, well the textbox is not per say databound, so refreshing it won't produce the change you desire, and to sleep 100 milliseconds => 1/10 of a second well it would very likely mess a bit with the example which has a time ticking each 250 ms and each time it does it will carry a sleep of something random between 0 and 2000 ms well it could've looked sequential without actually being.

See updated solution and please mark the question as answered if you consider it to be :)

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900