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
  • 11031

MethodInvoker和Invoker

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

MethodInvoker 委托

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

c#多线程 Invoke方法的使用

线程间操作无效: 从不是创建控件“”的线程访问它~~~的解决方法~线程间操作无效: 从不是创建控件“”的线程访问它。听说2003里边不会,我不知道是不是这样的,反正一直都在用05~05里会出这个问题的...
  • aaaaatiger
  • aaaaatiger
  • 2008年12月02日 17:33
  • 19282

MethodInvoker

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

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

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

C#中类型Type的GetMethod方法

C#中类型Type有个GetMethod方法,调用该方法可获取指定方法名的方法信息实例。 使用时,其参数一般为2个,一个是方法名称字符串(可设置条件忽略大小写),另外一个参数为搜索方法的条件枚举。 ...
  • fuyifang
  • fuyifang
  • 2016年11月04日 16:56
  • 1832

在winform下使初始化速度慢的数据可以在窗体显示之后再加载,这样就能提高用户体验

  • 2014年11月08日 07:31
  • 2KB
  • 下载

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

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

C# 使用绑定句柄来减少进程的内存耗用

许多应用程序中,绑定了一组类型(Type)或者类型成员(从MemberInfo派生),并将这些对象保存在某种形式的一个集合中。以后,会搜索这个集合,查找特定的对象,然后调用这个对象。这是一个很好的机制...
  • xunzaosiyecao
  • xunzaosiyecao
  • 2016年12月25日 10:03
  • 1102
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:C# 中MethodInvoker的理解
举报原因:
原因补充:

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