1. 程式人生 > >WPF的Dispatcher類裡的BeginInvoke,Invoke,InvokeAsync

WPF的Dispatcher類裡的BeginInvoke,Invoke,InvokeAsync

首先更深入的原理知識請移步:https://blog.csdn.net/WPwalter/article/details/78093917

這裡主要用上幾個例項。總結一下:

1.BeginInvoke和InvokeAsync原理一致,可取得一致的結果,用InvokeAsync會更實用方便,因為可以直接用上Action和Fun方法。

2.Invoke會阻塞執行緒,直到Invoke裡的程式碼完成,InvokeAsync和BeginInvoke會直接執行後面的程式碼。

來看一個簡單的例項:

private void btn_Click(object sender, RoutedEventArgs e)
        {
            Thread t = new Thread(DoSomeThing);
            t.Start();

            lable.Content= "1";
            this.Dispatcher.Invoke(() => { lable.Content += "2";Thread.Sleep(2000); });
            
            lable.Content += "3";
            
                

        }

        private void DoSomeThing()
        {
            for(int i=0;i<10;i++)
            {
                this.Dispatcher.Invoke(()=> { lable.Content += i.ToString(); });
                Thread.Sleep(1000);
            }
        }

結果是:

可以發現,先執行Invoke,然後執行Thread裡的內容。

接下來,把Invoke換成InvokeAsync。

private void btn_Click(object sender, RoutedEventArgs e)
        {
            Thread t = new Thread(DoSomeThing);
            t.Start();

            lable.Content= "1";
            this.Dispatcher.InvokeAsync(() => { lable.Content += "2";Thread.Sleep(2000); });
            lable.Content += "3";
        }

會發現結果變了。3在前,2在後,也就是說先執行了InvokeAsync。

接著再把DoSomeThing的Invoke也改成InvokeAsync,最後會發現結果中0變成了1,這是因為這裡的程序在排隊,先結束了btn_click裡的InvokeAsync,然後再來執行DoSomeThing裡的InvokeAsync,而此時i的值已經變成了1。

private void DoSomeThing()
        {
            for(int i=0;i<10;i++)
            {
                this.Dispatcher.InvokeAsync(()=> { lable.Content += i.ToString(); });
                Thread.Sleep(1000);
            }
        }