欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

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

程序员文章站 2022-03-04 12:34:21
...

个人的一点理解,参考了很多地方,比如
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;
        }
    }
}
相关标签: C# 多线程