尝试使用更改来自不同线程的UI控件属性.要求调用 [英] Trying to change UI control property from different thread using . InvokeRequired

查看:65
本文介绍了尝试使用更改来自不同线程的UI控件属性.要求调用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在做什么错了?

我的计划是从另一个线程更改标签文本属性,而不会出现跨线程操作无效"异常.

my plan is to change the label text property from a different thread without getting the "Cross-thread operation not valid" exception.

    private void button1_Click(object sender, EventArgs e)
    {
        Thread thread1 = new Thread(new ThreadStart(ChangeTime));
        thread1.Start();
    }

    delegate void SetTimeDelegate();

    private void ChangeTime()
    {
        while (true)
        {
            if (lbl1.InvokeRequired)
            {
                SetTimeDelegate setTime = new SetTimeDelegate(ChangeTime);
                lbl1.Invoke(setTime);


            }
            else
            {
                lbl1.Text = DateTime.Now.ToString("yyyy-MM-dd hh:mm:ss tt");
                Thread.Sleep(1000);
            }
        }
    }

推荐答案

要从其他线程更新UI控件,您需要调用BeginInvokeInvoke方法.您可以使用特定控件的方法或窗体的方法.

To update a UI control from a different thread you need to call the BeginInvoke or Invoke method. You can use the specific control's methods or the form's.

您的原始代码具有无限递归.您正在正确调用,除了您的委托正在调用相同的方法.创建一个单独的方法来随着时间更新标签,并委托该新方法.

Your original code has infinite recursion. You are Invoking correctly except your delegate is calling the same method. Create a separate method for updating the label with the time and have the delegate cll that new method.

private bool _IsShuttingDown = false;

private void ChangeTime()
{
   while (!_IsShuttingDown)
   {
      if (lbl1.InvokeRequired)
      {
         SetTimeDelegate setTime = new SetTimeDelegate(UpdateTimeLabel);
         lbl1.Invoke(setTime);
         Thread.Sleep(1000);
      }
      else
      {
         UpdateTimeLabel();
         Thread.Sleep(1000);
      }
   }
}

private void UpdateTimeLabel()
{
   lbl1.Text = DateTime.Now.ToString("yyyy-MM-dd hh:mm:ss tt");
}

protected override void OnClosing(CancelEventArgs e)
{
   _IsShuttingDown = true;
   base.OnClosing(e);
}

我还在表单上添加了一个字段,以在表单关闭或发生奇怪的事情时退出循环.

I also added a field on the form to exit the loop when the form is closing or else weird things happen.

我的原始代码:

if (lbl1.InvokeRequired)
{
    lbl1.Invoke((Action)(() => lbl1.Text = DateTime.Now.ToString("yyyy-MM-dd hh:mm:ss tt")));
    Thread.Sleep(1000);
}

这篇关于尝试使用更改来自不同线程的UI控件属性.要求调用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆