C# 中MethodInvoker的理解

原创 2015年07月09日 20:28:25


以下引用自:   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时间片的概念? 以前听说过线程插入进程, 但没听说过 线程也可以被插入啊?
















c#使用MethodInvoker解决跨线程访问控件

.net 原则上禁止跨线程访问控件,因为这样可能造成错误的发生,有一种方法是禁止编译器对跨线程访问作检查,Control.CheckForIllegalCrossThreadCalls = false...
  • ghevinn
  • ghevinn
  • 2013年09月26日 19:02
  • 10688

MethodInvoker 委托

MethodInvoker 提供一个简单委托,该委托用于调用含 void 参数列表的方法。在对控件的 Invoke 方法进行调用时或需要一个简单委托又不想自己定义时可以使用该委托(摘自MSDN)  ...

MethodInvoker和Invoker

using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; usin...
  • Joyhen
  • Joyhen
  • 2015年08月13日 12:01
  • 2424

MethodInvoker

在程序需要读取CAD文件列表中的文件信息,这是一个非常费时的操作,所以希望通过多线程的方式来实现,并且可以随时中止。由于初次使用多线程,开始的时候采用独立的线程类,该类返回数据,在Thread.Joi...

C#中Invoke 和 BeginInvoke 的区别

原文连接 相关资料:Invoke 和 BeginInvoke 的真正涵义 、在多线程中如何调用Winform Control.Invoke 方法 (Delegate) :在...

C#线程调用带参数的方法

转:C#线程调用带参数的方法--2 2007年06月15日 星期五 下午 11:24 个人认为,还是为线程创建一个单独的类,在类的初始化函数里头为类里头的变量赋值,来达到传入参数比较简单。下面有些方法...

任运自在:线程(Thread)与委托(Invoke和BeginInvoke)和封装

线程(Thread)与委托(Invoke和BeginInvoke) 这几天专门玩线程与委托,到处查找资料看,渐渐明白了用法、写法和一些注意事项; 描述: 什么是进程呢?当一个程序开始运行时,它就是一个...

python实现房价预测,采用回归和随机梯度下降法

from sklearn.datasets import load_boston boston = load_boston() from sklearn.cross_validation impo...

开启nginx的status和php-fpm的status页面

启用nginx status配置在默认主机里面加上location或者你希望能访问到的主机里面。server { location /nginx-status { stub_s...
  • keyunq
  • keyunq
  • 2016年11月30日 17:09
  • 1800

VS C++ MethodInvoker 倒数计时器

以下是一个使用了MethodInvoker的
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:C# 中MethodInvoker的理解
举报原因:
原因补充:

(最多只允许输入30个字)