C# wpf 使Invoke和BeginInvov在子線程中修改界面元素的示例

個人的一點理解,參考了很多地方,比如
https://www.cnblogs.com/zhangchenliang/p/4953649.html
http://www.cnblogs.com/yunmengyunxi/p/6066262.html

Invoke
  • 在Invoke封送的方法被執行完畢前,Invoke方法不會返回,從而調用者線程將被阻塞。
  • Invoke方法的同步阻塞是靠WaitHandle機制來完成的
BenginInvoke
  • 使用BeginInvoke方法封送一個委託方法,完畢後馬上返回,不會等待委託方法的執行結束,調用者線程將不會被阻塞。
  • 但是調用者也可以使用EndInvoke方法或者其它類似WaitHandle機制等待異步操作的完成

所以,Invoke =BenginInvoke + WaitHandle

這個示例是用兩個線程修改同一個文本塊

using System.Threading;
using System.Windows;

namespace WpfApp7
{
    /// <summary>
    /// MainWindow.xaml 的交互邏輯
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }
        
        //按鈕1開一個線程調用DoWork,這是一個調用委託的方法
        private void Button_Click(object sender, RoutedEventArgs e)
        {
            //線程中調用委託的調用方法
            Thread thread = new Thread(new ThreadStart(DoWork));
            thread.Start();
        }

        //按鈕2開一個線程調用DoWork2,同上
        private void Button2_Click(object sender, RoutedEventArgs e)
        {
            Thread thread = new Thread(new ThreadStart(DoWork2));
            thread.Start();
        }
        
        // 聲明委託
        public delegate void UpdateForm_dl(string str1);
        
        // DoWork調用委託,  
        // Invoke和BeginInvoke把消息送到主窗口的消息隊列中
        // 實際上的意思就是說,主窗口,你來調用修改文本塊的方法吧
        // Invoke 說,你調用完給我個話,我等着呢
        // BeginInvoke 說,告訴你了,我不管了
        private void DoWork() 
        {
            this.Dispatcher.BeginInvoke(new UpdateForm_dl(UpdateForm), "按鈕1被按下");
        }
        //同上
        private void DoWork2()
        {
            this.Dispatcher.Invoke(new UpdateForm_dl(UpdateForm), "按鈕2被按下");
        }
       
        //修改界面的功能
        private void UpdateForm(string str1)
    
        { 
            this.text1.Text = str1;
        }
    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章