天天看点

WPF 不阻塞UI线程更新UI的方式

WPF App中经常因为更新UI导致界面假死,无法操作的情况,下面我就更新UI不阻塞UI线程的方式,从2个方面测试。

WPF 不阻塞UI线程更新UI的方式

方式1, 使用System.Windows.Forms.Application.DoEvents() 方法

倒计时,UI从60,59 显示直到0.

        private int Num = 60;

        private void btnCount_Click(object sender, RoutedEventArgs e)

        {

            btnCount.IsEnabled = false;

            txtMsg.Text = Num.ToString();

            while(Num>0)

            {

                Num -= 1;

                txtMsg.Text = Num.ToString();

                System.Windows.Forms.Application.DoEvents();

                Thread.Sleep(100);

            }

            btnCount.IsEnabled = true;

        }

数字每减1,UI就更新显示一下,如果没有 System.Windows.Forms.Application.DoEvents();这个语句,UI就无法操作,拖动窗口时会卡死。

这个方式在拖动窗口时,倒计时会被阻塞,不执行。

使用System.Windows.Forms.Application.DoEvents()方法可以实时重绘窗体而避免出现画面假死的现象,但是使用System.Windows.Forms.Application.DoEvents()方法会带来一些效率上的问题,要是对效率有要求时,就需要考虑其他方式,如使用异步操作来完成耗时的循环操作

方式2:使用异步函数

        private async void btnCountAsync_Click(object sender, RoutedEventArgs e)

        {

            while(Num>0)

            {

                Num--;

                await UpdateUI(Num);

            }

        }

        async Task UpdateUI(int num)

        {

            txtMsg.Text = num.ToString();

            await Task.Delay(100);

        }

从测试情况看,方式2比方式1好,因为1在操作UI,比如拖动UI时,倒计时时不执行的,方式2,拖动UI(操作UI),这个异步方法在并执行,且UI也不会卡死。