Question

i have a strange situation.
please see the backgroundWorker5_RunWorkerCompleted event:

    private void backgroundWorker5_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
    {
        btnStartAdventures.Text = "Start Adventure";
        btnStartAdventures.Enabled = true;

        if (e.Error != null)
        {
            MessageBox.Show(e.Error.Message);
            return;
        }
        if (e.Cancelled)
        {
            lblStatusValueInAdventures.Text = "Cancelled...";
        }
        else
        {
            lblStatusValueInAdventures.Text = "Completed";
            timer1.Enabled = true;
            timer1.Start();
            // MessageBox.Show("start timer");
            Thread.Sleep((int.Parse(txtDelayInAdventures.Text)) * 60000);
            //MessageBox.Show("end timer");
            timer1.Enabled = false;
            timer1.Stop();
            lblTimer.Text = "0";
            btnStartAdventures.PerformClick();
        }
    }

and that Timer is :

private void timer1_Tick(object sender, EventArgs e)
{
    this.Invoke(new MethodInvoker(delegate { lblTimer.Text = (int.Parse(lblTimer.Text) + 1).ToString(); }));
}

but this timer can not change lblTimer's Text.
how can i fix this problem?

EDIT:
that Thread.Sleep is necessary and i can not remove it.
i want a loop that never ends and those codes are for that.

thanks in advance

Was it helpful?

Solution

As requested;

What do you mean by "a loop that never ends"? A Thread.Sleep on the UI thread (RunWorkerCompleted event executes on the UI thread) will effectively freeze the UI thread, which means that no interaction with the UI thread will be shown.

Comments:

What are you trying to achieve? As far as I can guess, you are doing some work in a background thread - backgroundWorker5 - (the UI thread is responsive). When backgroundWorker5 is finished you want to start a timer and display a counter in a label while the UI is still responsive (for somebody to stop the timer maybe?). Something like that? – Mario 3 mins ago edit

yes you are right. i want a loop and it never stops until a user click cancel button. – MoonLight 1 min ago

So, try something like this:

int time = 0;

private void backgroundWorker5_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
    btnStartAdventures.Text = "Start Adventure";
    btnStartAdventures.Enabled = true;

    if (e.Error != null)
    {
        MessageBox.Show(e.Error.Message);
        return;
    }
    if (e.Cancelled)
    {
        lblStatusValueInAdventures.Text = "Cancelled...";
    }
    else
    {
        lblStatusValueInAdventures.Text = "Completed";
        timer1.Interval = 1000; //<--- Tick each second, you can change this.
        timer1.Enabled = true;
        timer1.Start();
        // MessageBox.Show("start timer");
    }
}

private void timer1_Tick(object sender, EventArgs e)
{
    lblTimer.Text = (time + 1).ToString();
}

private void button_Cancel_Click(object sender, EventArgs e)
{
    //MessageBox.Show("end timer");
    timer1.Enabled = false;
    timer1.Stop();
    lblTimer.Text = "0";
    btnStartAdventures.PerformClick();
}

OTHER TIPS

Thread.Sleep

There's your problem.

Never call Thread.Sleep in a UI thread; it will freeze the UI.

Get rid of that, and it will work fine.

You can put the rest of the work in the timer callback.

You can also use C# 5 async to make this much simpler.

You have to refresh item.

lblTimer.Refresh()

and also you could refresh form

frmName.Refresh();

and make thread to sleep 0 milliseconds that gives space for other processes.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top