如何在计时器的刻度中更改标签的文本(GUI忙)

时间:2012-09-30 16:40:21

标签: c# .net-4.0 timer backgroundworker windows-applications

我有一个奇怪的情况 请参阅backgroundWorker5_RunWorkerCompleted活动:

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

并且Timer是:

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

但此计时器无法更改lblTimer's Text 我该如何解决这个问题?

修改
Thread.Sleep是必要的,我不能删除它 我想要一个永无止境的循环,那些代码就是为了这个。

提前致谢

3 个答案:

答案 0 :(得分:1)

Thread.Sleep

有你的问题。

永远不要在UI线程中调用Thread.Sleep;它会冻结用户界面。

摆脱它,它会正常工作。

您可以将剩下的工作放在计时器回调中。

您还可以使用C#5异步来简化这一过程。

答案 1 :(得分:1)

你必须刷新项目。

lblTimer.Refresh()

也可以刷新表单

frmName.Refresh();

并使线程休眠0毫秒,为其他进程提供空间。

答案 2 :(得分:1)

根据要求;

你是什么意思"一个永无止境的循环"? UI线程上的Thread.Sleep(在UI线程上执行RunWorkerCompleted事件)将有效地冻结UI线程,这意味着不会显示与UI线程的交互。

评论:

  

你想要达到什么目的?据我所知,你正在做   一些工作在后台线程 - backgroundWorker5 - (UI线程   是响应)。当backgroundWorker5完成后,你想要启动一个   在UI静止时,计时器并在标签中显示计数器   响应(有人可能会停止计时器?)。就像是   那? - 马里奥3分钟前编辑

     是的,你是对的。我想要一个循环,它永远不会停止,直到用户点击   取消按钮。 - MoonLight 1分钟前

所以,尝试这样的事情:

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