C#委托同步异步说明,并比较control调用Invoke和BeginInvoke的异同
一.委托的同步和异步:
1.同步
使用Invoke调用同步,或直接写fun1("func"),在fun1.Invoke这一步会明显的阻塞线程
使用:
- static void Main(string[] args)
- {
- Thread.CurrentThread.Name = "Main";
- //定义一个带返回值的委托
- var fun1 = new Func<string, int>(x =>
- {
- Thread.Sleep(1000);
- Console.WriteLine(x);
- Console.WriteLine($"ThreadId:{Thread.CurrentThread.ManagedThreadId} ThreadName:{Thread.CurrentThread.Name}");
- return 1;
- });
- fun1.Invoke("fun1");
- Console.WriteLine("Main");
- Console.WriteLine($"ThreadId:{Thread.CurrentThread.ManagedThreadId} ThreadName:{Thread.CurrentThread.Name}");
- Console.ReadKey();
- }
运行结果:
结果说明:
同步委托运行在主线程上
2.异步
使用BeginInvoke来调用异步,EndInvoke来获取返回值,AsyncCallback定义异步完成回调函数
使用:
- static void Main(string[] args)
- {
- Thread.CurrentThread.Name = "Main";
- //定义一个带返回值的委托
- var fun1 = new Func<string, int>(x =>
- {
- Thread.CurrentThread.Name = "fun1";
- Console.WriteLine(x);
- Console.WriteLine($"ThreadId:{Thread.CurrentThread.ManagedThreadId} ThreadName:{Thread.CurrentThread.Name}");
- return 1;
- });
- fun1.BeginInvoke("fun1", t =>
- {
- //var fun2 = t.AsyncState as Func<string, int>;//如果不是lambda表达式需要用该方式获得委托
- //获取返回值
- int ret = fun1.EndInvoke(t);
- Console.WriteLine($"callback return:{ret}");
- Console.WriteLine($"ThreadId:{Thread.CurrentThread.ManagedThreadId} ThreadName:{Thread.CurrentThread.Name}");
- }, null);
- Thread.Sleep(1000);
- Console.WriteLine("Main");
- Console.WriteLine($"ThreadId:{Thread.CurrentThread.ManagedThreadId} ThreadName:{Thread.CurrentThread.Name}");
- Console.ReadKey();
- }
运行结果:
结果说明:
异步委托并不是运行在主线程上,而是运行在独立的线程上,是异步执行的
二.control的Invoke和BeginInvoke
1.Invoke
使用:
- private void button1_Click(object sender, EventArgs e)
- {
- Thread.CurrentThread.Name = "UIThread";
- this.Invoke(new Action(() =>
- {
- Thread.Sleep(5000);
- Debug.WriteLine($"Invoke ThreadId:{Thread.CurrentThread.ManagedThreadId} ThreadName:{Thread.CurrentThread.Name}");
- }));
- Debug.WriteLine($"Main ThreadId:{Thread.CurrentThread.ManagedThreadId} ThreadName:{Thread.CurrentThread.Name}");
- }
运行结果:
结果说明:
可以明显的感到Invoke阻塞了界面5s后,才执行后面的代码
Invoke内的委托在UI线程上执行,是同步的
2.BeginInvoke
使用:
- private void button1_Click(object sender, EventArgs e)
- {
- Thread.CurrentThread.Name = "UIThread";
- this.BeginInvoke(new Action(() =>
- {
- Debug.WriteLine($"BeginInvoke ThreadId:{Thread.CurrentThread.ManagedThreadId} ThreadName:{Thread.CurrentThread.Name}");
- }));
- Debug.WriteLine($"Main ThreadId:{Thread.CurrentThread.ManagedThreadId} ThreadName:{Thread.CurrentThread.Name}");
- Thread.Sleep(5000);
- }
运行结果:
结果说明:
可以明显看到界面卡了5s后,才先执行的BeginInvoke内的委托
结论:BeginInvoke内的委托在UI线程上执行,并不是异步,只是放在UI线程中最后执行。
三.结论
delegate.Invoke | 运行在主线程上,同步执行,并立即执行,会阻塞主线程 |
delegate.BeginInvoke | 运行在独立线程上,异步执行, 并立即执行,不会阻塞主线程 |
Control.Invoke | 运行在UI线程上,同步执行,并立即执行,会阻塞UI线程 |
Control.BeginInvoke | 运行在UI线程上,不是异步执行,等UI线程其他操作完成才执行,会阻塞UI线程 |
C#委托同步异步说明,并比较control调用Invoke和BeginInvoke的异同的更多相关文章
- Control的Invoke和BeginInvoke详解
(一)Control的Invoke和BeginInvoke 我们要基于以下认识: (1)Control的Invoke和BeginInvoke与Delegate的Invoke和BeginInvoke是不 ...
- [转]Control的Invoke和BeginInvoke
转自:Control的Invoke和BeginInvoke 作者:Kuffy Wang 近日,被Control的Invoke和BeginInvoke搞的头大,就查了些相关的资料,整理如下.感谢这篇文 ...
- C#中Control的Invoke和BeginInvoke是相对于支线线程
近日,被Control的Invoke和BeginInvoke搞的头大,就查了些相关的资料,整理如下. Control的Invoke和BeginInvoke 是相对于支线线程(因为一般在支线线程中调用, ...
- Control的Invoke和BeginInvoke
转载:https://www.cnblogs.com/c2303191/articles/826571.html 近日,被Control的Invoke和BeginInvoke搞的头大,就查了些相关的资 ...
- 【分析】浅谈C#中Control的Invoke与BeginInvoke在主副线程中的执行顺序和区别(SamWang)
[分析]浅谈C#中Control的Invoke与BeginInvoke在主副线程中的执行顺序和区别(SamWang) 今天无意中看到有关Invoke和BeginInvoke的一些资料,不太清楚它们之间 ...
- [转载]Winform中Control的Invoke与BeginInvoke方法
转自http://www.cppblog.com/baby-fly/archive/2010/04/01/111245.html 一.为什么 Control类提供了 Invoke和 BeginInvo ...
- 委托(delegate)的三种调用方式:同步调用,异步调用,异步回调(转载)
下面为即将被调用的方法: public delegate int AddHandler(int a,int b); public class 加法类 { public static int Add(i ...
- C#--委托的同步,异步,回调函数
原文地址 同步调用 委托的Invoke方法用来进行同步调用.同步调用也可以叫阻塞调用,它将阻塞当前线程,然后执行调用,调用完毕后再继续向下进行. using System; using System. ...
- C#使用委托进行异步编程。
首先引用MSDN中的一段话来描述一下如何使用异步方式.NET Framework 允许您异步调用任何方法. 为此,应定义与您要调用的方法具有相同签名的委托:公共语言运行时会自动使用适当的签名为该委托定 ...
随机推荐
- Ubuntu apt-get卸载小记
过sudo apt-get install xxxx 安装软件后,总是无法卸载干净,这里以Apache 为例,提供方法:首先sudo apt-get remove apache2再sudo apt-g ...
- Centos 6.5 安装Oracle 11g R2 on vbox
由于上一篇的rac安装,截图较多,这一篇选择以txt的方式叙述,另外上一篇的时间比较久远,这里最近从新安装 --2018-10-29 1 os环境初始化 [root@rac1 yum.repos.d] ...
- StarkSoft题库管理系统
一.功能介绍 1.自定义试题库管理系统目录.难易程度,题型,知识库等. 2.试题录入. 3.强大的试题编辑功能,并与通常应用编辑工具有共通. 4.灵活的试卷构造功能,用户可自定 ...
- Web验证码图片的生成-基于Java的实现
验证码图片是由程序动态产生的,每次访问的内容都是随机的.那么如何采用程序动态产生图片,并能够显示在客户端页面中呢?原理很简单,对于java而言,我们首先开发一个Servlet,这个Servlet的任务 ...
- JeeSite基础知识(一)
- python's twenty-sixth day for me 模块
configparser 模块: 该模块适用于配置文件的格式与windows ini文件类似,可以包含一个或多个节(section),每个节可以有多个参数(键 = 值). 创建文件: # 创建文件 i ...
- PHP_File文件操作简单常用函数
php测试文件 <?php header("Content-type:text/html;charest=utf-8");$fileDir='Upload/File/cont ...
- Tornado 高并发源码分析之二---Tornado启动和请求处理流程
Tornado 服务器启动流程 因为Tornado 里使用了很多传类的方式,也就是delegate,之所以要这么做,其实和 iOS 开发那样,也很多的 delegate, 如此来实现高度解耦,但是比较 ...
- 【bzoj3940】[Usaco2015 Feb]Censoring
[题目描述] FJ把杂志上所有的文章摘抄了下来并把它变成了一个长度不超过10^5的字符串S.他有一个包含n个单词的列表,列表里的n个单词 记为t_1...t_N.他希望从S中删除这些单词. FJ每次 ...
- 581. Shortest Unsorted Continuous Subarray连续数组中的递增异常情况
[抄题]: Given an integer array, you need to find one continuous subarray that if you only sort this su ...