C# 在主 UI 线程上执行工作时更新运行时间

本文关键字:工作 更新 运行时间 执行 在主 UI 线程 | 更新日期: 2023-09-27 18:32:09

我有以下代码使用后台线程中的经过时间更新标签。 我希望在通过按下按钮模拟的主 UI 线程上做大量工作时继续这样做。 我想让 UI 保持繁忙,以便用户无法完成其他操作。 如何做到这一点?

using System.ComponentModel;
using System.Windows.Forms;
using System.Diagnostics;
using System.Threading;
namespace WindowsFormsApplication1
{
    public partial class Form1 : Form
    {
        private BackgroundWorker _worker;
        Stopwatch _watch = null;
        public Form1()
        {
            InitializeComponent();
            InitWorker();
            _watch = Stopwatch.StartNew();
        }
        private void InitWorker()
        {
            if (_worker != null)
            {
                _worker.Dispose();
            }
            _worker = new BackgroundWorker
            {
                WorkerReportsProgress = true,
                WorkerSupportsCancellation = true
            };
            _worker.DoWork += DoWork;
            _worker.RunWorkerAsync();
        }

        void DoWork(object sender, DoWorkEventArgs e)
        {
            while (_watch != null)
            {
                label1.Invoke((MethodInvoker)delegate
                {
                    label1.Text = _watch.Elapsed.ToString(@"hh':mm':ss");
                });
                Thread.Sleep(1000);
            }
        }
        private void button1_Click(object sender, System.EventArgs e)
        {
            for (int i = 0; i < 1000000000; i++)
            {
                double a = 600000000000000.5;
                a = a / 4.54;
            }
        }
    }
}

C# 在主 UI 线程上执行工作时更新运行时间

只要您阻止 UI 线程,UI 就会被冻结,无法处理任何调用(他们怎么可能?他们将代码封送到繁忙的 UI 线程)。

此策略不起作用。

如果要阻止 UI,请不要冻结它。您可能应该禁用您关心的所有输入元素。一个激进的解决方案是在窗体的整个客户区域上覆盖一个透明面板。不过,这对用户来说很奇怪。

如果您不知道:您可以使用 await Task.Run(...); 在后台线程上轻松运行昂贵的工作。 BackgroundWorker已经过时了。