C#更新主UI线程

时间:2016-01-26 17:03:10

标签: c# multithreading timer

我有以下代码更新标签,其中包含后台线程中的已用时间。我想在按下按钮模拟的主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;
            }
        }
    }
}

1 个答案:

答案 0 :(得分:0)

只要您阻止UI线程,UI就会被冻结,就不能处理任何Invoke(它们怎么可能?它们将代码编组到忙线的UI线程中。)

此策略无效。

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

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

相关问题