Kountay Dwivedi
Kountay Dwivedi

Reputation: 27

C#: How to execute thread without halting program execution

I am making a memory game. Whenever user clicks on a button, an image is revealed. Then user has to click on another button. If both images match, then buttons are replaced by a tick mark. If not, then there is a 1 sec gap for the user to memorize the image location..and then again, images are hidden and buttons are shown. I do the 1 sec gap by Thread.Sleep(1000)

I have embedded a countdown timer in the game whose duration is 30 sec. I have placed a label which shows the 30 second countdown on each clock tick.


Now the actual problem is, that whenever Thread.Sleep(1000) is invoked, the timer halts. And after 1 sec, it resumes. I want this timer to execute regardless of Thread. Please help.

Upvotes: 0

Views: 117

Answers (1)

Mike Goodwin
Mike Goodwin

Reputation: 8880

It's a little hard to understand exactly what you are asking, so apologies if I've misunderstood you, but I think you are asking how you can update the UI using a timer on a new thread without blocking the UI thread? The answer is that you cannot update a UI control in a thread other than the one that it was created in. Instead you have to create a delegate to do it for you.

So, this gives you an exception because the callback UpdateText at the end of the timer executes on the timer thread, not the main UI thread:

private void button1_Click(object sender, EventArgs e)
{
    System.Threading.Timer timer = new System.Threading.Timer(UpdateText, null, 1000, System.Threading.Timeout.Infinite);
}

public void UpdateText(object state)
{
    this.textBox1.AppendText("Ouch!" + Environment.NewLine);
}

Whereas, this works as expected: When you click the button, one second later the word "Ouch!" appears in the text box. This is because the use of the BeginInvoke method on the textbox control with the MethodInvoker delegate causes the delegate to execute on the thread that owns the control (i.e. the main UI thread) rather than on the timer thread:

private void button1_Click(object sender, EventArgs e)
{
    System.Threading.Timer timer = new System.Threading.Timer(UpdateText, null, 1000, System.Threading.Timeout.Infinite);
}

public void UpdateText(object state)
{
    MethodInvoker action = delegate
    {
        this.textBox1.AppendText("Ouch!" + Environment.NewLine);
    };

    this.textBox1.BeginInvoke(action);
}

Upvotes: 2

Related Questions