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 允许您异步调用任何方法. 为此,应定义与您要调用的方法具有相同签名的委托:公共语言运行时会自动使用适当的签名为该委托定 ...
随机推荐
- kali下apche配置多网站
设置文件地址为 :/etc/apache2/sites-available/default 添加: <VirtualHost *:80> ServerName www.php. ...
- python学习(十六) 测试
测试驱动开发. 16.1 先测试,后编码 16.1.1 精确的需求说明 16.1.2 为改变而计划 16.1.3 测试的4个步骤 16.2 测试工具 16.2.1 doctest 16.2.2 uni ...
- verilog HDL 编码风格
1.有意义且有效的名字. 2.同一信号在不同层次应该保持一致. 3.添加有意义的后缀,使信号的有效性更加明确. 4.模块输出寄存器化,使得输出的驱动强度和输入延时是可以预测的. 5.使用括号表明优先级 ...
- 用css实现图片在div内的垂直居中
已知一个div内有一个img,两者的高度均不知道,但图片的高度一定小于div的高度 代码如下: .box { /*非IE的主流浏览器识别的垂直居中的方法*/ display: table-cell; ...
- 实验吧CTF题库-WEB题(部分)
看起来有点难 提交admin http://ctf5.shiyanbar.com/basic/inject/index.php?admin=admin&pass=admin&actio ...
- Spring AOP基于注解的“零配置”方式实现
为了在Spring中启动@AspectJ支持,需要在类加载路径下新增两个AspectJ库:aspectjweaver.jar和aspectjrt.jar.除此之外,Spring AOP还需要依赖一个a ...
- Halcon学习之边缘检测函数
sobel_amp ( Image : EdgeAmplitude : FilterType, Size : ) 根据图像的一次导数计算图像的边缘 close_edges ( Edges, EdgeI ...
- EXT.net 窗体传值
ext.net 窗体传值 EXT.net 窗体传值 子窗体代码 protected void btnClose_Click(object sender,EventArges e) { PageCont ...
- document.ready与window.load区别
jQuery document window load ready 区别详解 用过JavaScript的童鞋,应该知道window对象和document对象,也应该听说过load事件和ready事件, ...
- 【bzoj1018】[SHOI2008]堵塞的交通traffic
1018: [SHOI2008]堵塞的交通traffic Time Limit: 3 Sec Memory Limit: 162 MBSubmit: 2887 Solved: 954[Submit ...