Dispatcher的Invoke和BeginInvoke


WPF的應用程序運行時,就有一個主線程(UI線程)和其他的一些子線程。

子線程是不能修改UI線程,必須通過UI線程的Dispatcher來完成。

簡單點來說:子線程是不能修改程序UI的,除非用UI線程的Dispatcher來注冊。

例如:

private void Invoke_Button(object sender, RoutedEventArgs e)
  {
            Task.Run(() =>
            {
                Thread.Sleep(1000);
                this.TextBlock.Text = "10";
            });
        }

另起一個線程去修改UI上TextBlock控件的值。就會報異常:System.InvalidOperationException: '調用線程無法訪問此對象,因為另一個線程擁有該對象。'

Dispatcher兩種注冊方式:

Invoke:同步調用,即會在子線程執行完成后返回。

private void Invoke_Button(object sender, RoutedEventArgs e)
        {
            Task.Run(() =>
            {
                Dispatcher.Invoke(() =>
                {
                    Thread.Sleep(5000);
                    this.TextBlock.Text = "10";
                });
            });
        }

BeginInvoke:異步調用,即立即返回。

private void BeginInvoke_Button(object sender, RoutedEventArgs e)
        {
            Task.Run(() =>
            {
                Dispatcher.BeginInvoke(DispatcherPriority.Normal, new Action(() =>
                {
                    this.TextBlock.Text = "3";
                    Thread.Sleep(10000);
                }));
            });
        }

總結:當在子線程中調用Dispather注冊時,Dispatcher中的Action依然還是占用着UI線程,所以Dispatcher的工作項依然是越少越少,耗時操作越少越好。

BeginInvoke效率要更高一點。反應更靈敏。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM