C# 中MethodInvoker的理解



以下引用自:   c#使用MethodInvoker解决跨线程访问控件

net 原则上禁止跨线程访问控件,因为这样可能造成错误的发生,有一种方法是禁止编译器对跨线程访问作检查,Control.CheckForIllegalCrossThreadCalls = false;可以实现访问,但是出不出错不敢保证C#跨线程访问控件运行时错误。

使用MethodInvoker即可解决


看看系统定义, 与event 的区别

public delegate void MethodInvoker();

public delegate void EventHandler(object sender, EventArgs e);

简单来说 :

MethodInvoker 是不带参数的委托。
EventHandler 是可带参数的委托


我是这样理解的, 开启新线程 threadRun,   在新线程中使用MethodInvoker 委托执行 run()方法, 这个时候 run() 方法其实是在主线程中执行的, 这样就避免了 跨线程访问控件, 以下是我的测试代码:

        private void button1_Click(object sender, EventArgs e)
        {
            Thread.CurrentThread.Name = "MainThread";       //主线程命名为 MainThread
            Thread td = new Thread(threadRun);
            td.Name = "ChildThread";                        //子线程命名为 ChildThread
            td.Start();
        }

        private void ChangeText()
        {
            this.textBox1.Text = Thread.CurrentThread.Name; //TextBox1内容被修改的线程的名字
        }

        private void threadRun()
        {
            MessageBox.Show(Thread.CurrentThread.Name);     //弹出对话框, 当前运行线程的名字
            MethodInvoker In = new MethodInvoker(ChangeText);
            this.BeginInvoke(In);
        


运行后, 点击 Button 首先弹出对话框 ChildThread, 然后 TextBox1 改为 MainThread


然后我的牛角劲又来了, ChangeText 被 MethodInvoker 插入到主线程中运行, 那么 ChangeText 应该是在 button1_Click 完全结束后才运行吧, 测试代码

        private void button1_Click(object sender, EventArgs e)
        {
            Thread.CurrentThread.Name = "MainThread";       //主线程命名为 MainThread
            Thread td = new Thread(threadRun);
            td.Name = "ChildThread";                        //子线程命名为 ChildThread
            td.Start();

            int k=0;                                        //让主线程全速运行一段时间
            for (long i = 0; i < 1000000000; i++)
            {
                if (k > 10000) k = 0;
                k = k+5;
            }
            MessageBox.Show("MainThread全速运算刚刚结束了");
        }

        private void ChangeText()
        {
            MessageBox.Show(Thread.CurrentThread.Name);     //弹出执行ChangeText的线程的名字
        }

        private void threadRun()
        {
            MessageBox.Show(Thread.CurrentThread.Name);     //弹出对话框, 当前运行线程的名字
            MethodInvoker In = new MethodInvoker(ChangeText);
            this.BeginInvoke(In);
        }


可惜并不是我想的那样, 运行情况是先弹出 ChildThread, 然后弹出 MainThread, 最后才弹出 MainThread全速运算刚刚结束了

有谁可以解释一下么???????????? 难道同一个线程也有CPU时间片的概念? 以前听说过线程插入进程, 但没听说过 线程也可以被插入啊?















阅读更多
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页

加入CSDN,享受更精准的内容推荐,与500万程序员共同成长!
关闭
关闭