我理解的invoke和begininvoke 一直对invoke和begininvoke的使用和概念比较混乱,这两天看了些资料,对这两个的用法和原理有了些新的认识和理解。 首先说下,invoke和begininvoke的使用有两种情况: 1. control中的invoke、begi
2012-05-03 10:28
597 查看
一直对invoke和begininvoke的使用和概念比较混乱,这两天看了些资料,对这两个的用法和原理有了些新的认识和理解。 首先说下,invoke和begininvoke的使用有两种情况:
1. control中的invoke、begininvoke。
2. delegrate中的invoke、begininvoke。
这两种情况是不同的,我们这里要讲的是第1种。下面我们在来说下.NET中对invoke和begininvoke的官方定义。
control.invoke(参数delegate)方法:在拥有此控件的基础窗口句柄的线程上执行指定的委托。
control.begininvoke(参数delegate)方法:在创建控件的基础句柄所在线程上异步执行指定委托。
根据这两个概念我们大致理解invoke表是同步、begininvoke表示异步。但是如何来进行同步和异步呢?我们来做一个测试。
invoke 例子:
private void button1_Click(object sender, EventArgs e)
{
MessageBox.Show(Thread.CurrentThread.GetHashCode().ToString()+"AAA");
invokeThread = new Thread(new ThreadStart(StartMethod));
invokeThread.Start();
string a = string.Empty;
for (int i = 0; i < 3; i++) //调整循环次数,看的会更清楚
{
Thread.Sleep(1000);
a = a + "B";
}
MessageBox.Show(Thread.CurrentThread.GetHashCode().ToString()+a);
}
private void StartMethod()
{
MessageBox.Show(Thread.CurrentThread.GetHashCode().ToString()+"CCC");
button1.Invoke(new invokeDelegate(invokeMethod));
MessageBox.Show(Thread.CurrentThread.GetHashCode().ToString()+"DDD");
}
private void invokeMethod()
{
//Thread.Sleep(3000);
MessageBox.Show(Thread.CurrentThread.GetHashCode().ToString() + "EEE");
}
结论:我们运行后,看下程序的运行顺序,1AAA->3CCC和1BBB->1EEE ->3DDD 。
解释:主线程运行1AAA,然后1BBB和子线程3CCC同时执行,然后通过invoke来将invokemethod方法提交给主线程,然后子线 程等待主线程执行,直到主线程将invokemethod方法执行完成(期间必须等待主线程的任务执行完成,才会去执行invoke提交的任务),最后执 行子线程3DDD。
begininvoke 例子:
private void button1_Click(object sender, EventArgs e)
{
MessageBox.Show(Thread.CurrentThread.GetHashCode().ToString()+"AAA");
invokeThread = new Thread(new ThreadStart(StartMethod));
invokeThread.Start();
string a = string.Empty;
for (int i = 0; i < 3; i++) //调整循环次数,看的会更清楚
{
Thread.Sleep(1000);
a = a + "B";
}
MessageBox.Show(Thread.CurrentThread.GetHashCode().ToString()+a);
}
private void StartMethod()
{
MessageBox.Show(Thread.CurrentThread.GetHashCode().ToString()+"CCC");
button1.BeginInvoke(new invokeDelegate(invokeMethod));
MessageBox.Show(Thread.CurrentThread.GetHashCode().ToString()+"DDD");
}
private void beginInvokeMethod()
{
//Thread.Sleep(3000);
MessageBox.Show(Thread.CurrentThread.GetHashCode().ToString() + "EEEEEEEEEEEE");
}
结论: 我们运行后看看执行的结果:1AAA->1BBB和3CCC->1EEE和3DDD。
解释: 主线程运行1AAA,然后1BBB和子线程3CCC同时执行,然后通过begininvoke来将invokemethod方法提交给主线程,然后主线程执行1EEE(主线程自己的任务执行完成), 同时子线程继续执行3DDD。
通过这个两段代码的测试比较,我们会发现其实invoke和begininvoke所提交的委托方法都是在主线程中执行的,其实根据我invoke 和begininvoke的定义我们要在子线程中来看这个问题,在invoke例子中我们会发现invoke所提交的委托方法执行完成后,才能继续执行 DDD;在begininvoke例子中我们会发现begininvoke所提交的委托方法后,子线程讲继续执行DDD,不需要等待委托方法的完成。 那么现在我们在回想下invoke(同步)和begininvoke(异步)的概念,其实它们所说的意思是相对于子线程而言的,其实对于控件的调用总是由 主线程来执行的。我们很多人搞不清这个同步和异步,主要还是因为我们把参照物选错了。其实有时候光看概念是很容易理解错误的。
1. control中的invoke、begininvoke。
2. delegrate中的invoke、begininvoke。
这两种情况是不同的,我们这里要讲的是第1种。下面我们在来说下.NET中对invoke和begininvoke的官方定义。
control.invoke(参数delegate)方法:在拥有此控件的基础窗口句柄的线程上执行指定的委托。
control.begininvoke(参数delegate)方法:在创建控件的基础句柄所在线程上异步执行指定委托。
根据这两个概念我们大致理解invoke表是同步、begininvoke表示异步。但是如何来进行同步和异步呢?我们来做一个测试。
invoke 例子:
private void button1_Click(object sender, EventArgs e)
{
MessageBox.Show(Thread.CurrentThread.GetHashCode().ToString()+"AAA");
invokeThread = new Thread(new ThreadStart(StartMethod));
invokeThread.Start();
string a = string.Empty;
for (int i = 0; i < 3; i++) //调整循环次数,看的会更清楚
{
Thread.Sleep(1000);
a = a + "B";
}
MessageBox.Show(Thread.CurrentThread.GetHashCode().ToString()+a);
}
private void StartMethod()
{
MessageBox.Show(Thread.CurrentThread.GetHashCode().ToString()+"CCC");
button1.Invoke(new invokeDelegate(invokeMethod));
MessageBox.Show(Thread.CurrentThread.GetHashCode().ToString()+"DDD");
}
private void invokeMethod()
{
//Thread.Sleep(3000);
MessageBox.Show(Thread.CurrentThread.GetHashCode().ToString() + "EEE");
}
结论:我们运行后,看下程序的运行顺序,1AAA->3CCC和1BBB->1EEE ->3DDD 。
解释:主线程运行1AAA,然后1BBB和子线程3CCC同时执行,然后通过invoke来将invokemethod方法提交给主线程,然后子线 程等待主线程执行,直到主线程将invokemethod方法执行完成(期间必须等待主线程的任务执行完成,才会去执行invoke提交的任务),最后执 行子线程3DDD。
begininvoke 例子:
private void button1_Click(object sender, EventArgs e)
{
MessageBox.Show(Thread.CurrentThread.GetHashCode().ToString()+"AAA");
invokeThread = new Thread(new ThreadStart(StartMethod));
invokeThread.Start();
string a = string.Empty;
for (int i = 0; i < 3; i++) //调整循环次数,看的会更清楚
{
Thread.Sleep(1000);
a = a + "B";
}
MessageBox.Show(Thread.CurrentThread.GetHashCode().ToString()+a);
}
private void StartMethod()
{
MessageBox.Show(Thread.CurrentThread.GetHashCode().ToString()+"CCC");
button1.BeginInvoke(new invokeDelegate(invokeMethod));
MessageBox.Show(Thread.CurrentThread.GetHashCode().ToString()+"DDD");
}
private void beginInvokeMethod()
{
//Thread.Sleep(3000);
MessageBox.Show(Thread.CurrentThread.GetHashCode().ToString() + "EEEEEEEEEEEE");
}
结论: 我们运行后看看执行的结果:1AAA->1BBB和3CCC->1EEE和3DDD。
解释: 主线程运行1AAA,然后1BBB和子线程3CCC同时执行,然后通过begininvoke来将invokemethod方法提交给主线程,然后主线程执行1EEE(主线程自己的任务执行完成), 同时子线程继续执行3DDD。
通过这个两段代码的测试比较,我们会发现其实invoke和begininvoke所提交的委托方法都是在主线程中执行的,其实根据我invoke 和begininvoke的定义我们要在子线程中来看这个问题,在invoke例子中我们会发现invoke所提交的委托方法执行完成后,才能继续执行 DDD;在begininvoke例子中我们会发现begininvoke所提交的委托方法后,子线程讲继续执行DDD,不需要等待委托方法的完成。 那么现在我们在回想下invoke(同步)和begininvoke(异步)的概念,其实它们所说的意思是相对于子线程而言的,其实对于控件的调用总是由 主线程来执行的。我们很多人搞不清这个同步和异步,主要还是因为我们把参照物选错了。其实有时候光看概念是很容易理解错误的。
相关文章推荐
- Java第七课 Java的多线程程序进程和线程的概念,实现多线程的两种方式,线程同步的原理,线程的死锁,运用wait和notify来实现producer - consumer关系,线程终止的两种情况。
- cc150:使用两个栈实现一个队列(两种方法比较)
- 使用JAVA实现比较两个文件夹下的文件新增和修改情况,并复制到新的目录(实现增量更新项目)
- C++优先级队列中,比较函数使用的两种情况:
- java 比较两个对象属性值变化情况,用于记录日志使用
- OpenvSwitch概念和原理的理解与使用技巧
- Java之戳中痛点 - (3)三目运算符的两个操作数类型尽量一致 Java之戳中痛点 - (4)i++ 和 ++i 探究原理 Java之戳中痛点 - (1)易变业务使用脚本语言编写 Java之戳中痛点 - (2)取余用偶判断,不要用奇判断 (5)switch语句break不能忘以及default不同位置的用法 Java之戳中痛点 - (7)善用Java整型缓存池
- 要理解__doPostback函数的用法,首先我们要理解Asp.net 中服务端控件事件是如何触发的。 Asp.net 中在客户端触发服务端事件分为三种情况: 一. WebControls中
- Windows Phone 多线程-Thread与BeginInvoke的区别-多种多线程编程比较
- 使用C++模板和不使用C++模板两种情况中的执行代码大小近似估计
- 使用AsyncTask异步加载类进行访问网络数据json的理解和用法
- 对Java中使用两个大括号进行初始化的理解
- spring 概念理解(资料)
- 使用C++模板和不使用C++模板两种情况中的执行代码大小近似估计
- 通过JVM原理理解字符串的比较
- 得到网络端口使用情况的两个函数
- T-SQL查询进阶--理解SQL Server中索引的概念,原理以及其他
- bzcmp命令_Linux bzcmp 命令用法详解:比较两个压缩包中的文件
- 两个Windows基本概念:Folder/Directory, 资料夹/文件夹
- java中几种Map在什么情况下使用,并简单介绍原因及原理