用户界面-线程期间更新UI(Windows窗体,C#)

本文关键字:窗体 Windows UI 线程 更新 用户界面 | 更新日期: 2023-09-27 17:57:47

我已经为这个问题挣扎了一段时间,我似乎不是唯一一个。关于这个话题有很多线索,但似乎没有一个对我有用。希望这里有人能给我指明正确的方向。

总结:我创建了一个带有许多控件的windows窗体。用户可以设置这些控件,然后"启动"测试。这会触发一个线程,这样我仍然可以在测试期间访问windows表单(这可能会持续数周)。我想在这个线程中更新UI,但是,我还没有弄清楚如何做到这一点。

我写了一个非常小的windows窗体应用程序,认为用它来解释我的问题会更容易,然后我可以使用这里给出的建议来解决我的大问题。

这是我的小程序的代码,目前还没有编译

using System;
using System.Threading;
using System.Windows.Forms;
namespace WindowsFormsApplication2
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }
        private void button1_Click(object sender, EventArgs e)
        {
            Thread thread = new Thread(() => startNewThread());
            thread.Start();
        }
        public static void startNewThread()
        {
            for (int i = 0; i < 10; i++)
            {
                Thread.Sleep(1000);
                string text = string.Format("Time: [{0}]", i);
                label1.Invoke((Action)delegate { label1.Text = text; });
            }
        }
    }
}

我试图使用@JaredPar在这个帖子中给出的建议,但我无法让它为我工作。然而,我的意图是点击按钮,转到帖子,更新帖子中的标签。就像我说的,我还不能编译,并收到以下错误:

An object reference is required for the non-static field, method, or property 'Form1.label1'

任何帮助都将不胜感激,我为我缺乏知识而道歉,因为我认为这是完全基本的。我每天都在学习。

提前感谢

用户界面-线程期间更新UI(Windows窗体,C#)

只是为了解决您的问题:

  1. 线程函数不能是静态的
  2. 使用这个。调用而不是Label.Invoke

但是,如果您总是希望定期并在一致的时间内更新UI,则更好的解决方案是使用System.Windows.Timer,这是一个在主UI线程上运行的计时器,并按初始化间隔计时。那么您就不必使用Invoke方法了。

看看这里:https://msdn.microsoft.com/en-us/library/system.windows.forms.timer(v=vs.110).aspx

处理UI线程可能很棘手。这是一个对我来说很方便的技巧。将以下扩展方法添加到您的项目中。

public static class WindowsFormsControlExtensions
{
    public static void Invoke(this Control control, Action action)
    {
        control.Invoke(action);
    }
}

在表单类中添加方法时,可以使用扩展,如下所示。this关键字将引用表单,并且包含的代码将在包含表单句柄的线程上执行。

public void SetLabel(string text)
{
    this.Invoke(() =>
    {
        if (label1 != null)
            label1.Text = text;
    });
}