一.委托的同步和异步:

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的异同的更多相关文章

  1. Control的Invoke和BeginInvoke详解

    (一)Control的Invoke和BeginInvoke 我们要基于以下认识: (1)Control的Invoke和BeginInvoke与Delegate的Invoke和BeginInvoke是不 ...

  2. [转]Control的Invoke和BeginInvoke

    转自:Control的Invoke和BeginInvoke  作者:Kuffy Wang 近日,被Control的Invoke和BeginInvoke搞的头大,就查了些相关的资料,整理如下.感谢这篇文 ...

  3. C#中Control的Invoke和BeginInvoke是相对于支线线程

    近日,被Control的Invoke和BeginInvoke搞的头大,就查了些相关的资料,整理如下. Control的Invoke和BeginInvoke 是相对于支线线程(因为一般在支线线程中调用, ...

  4. Control的Invoke和BeginInvoke

    转载:https://www.cnblogs.com/c2303191/articles/826571.html 近日,被Control的Invoke和BeginInvoke搞的头大,就查了些相关的资 ...

  5. 【分析】浅谈C#中Control的Invoke与BeginInvoke在主副线程中的执行顺序和区别(SamWang)

    [分析]浅谈C#中Control的Invoke与BeginInvoke在主副线程中的执行顺序和区别(SamWang) 今天无意中看到有关Invoke和BeginInvoke的一些资料,不太清楚它们之间 ...

  6. [转载]Winform中Control的Invoke与BeginInvoke方法

    转自http://www.cppblog.com/baby-fly/archive/2010/04/01/111245.html 一.为什么 Control类提供了 Invoke和 BeginInvo ...

  7. 委托(delegate)的三种调用方式:同步调用,异步调用,异步回调(转载)

    下面为即将被调用的方法: public delegate int AddHandler(int a,int b); public class 加法类 { public static int Add(i ...

  8. C#--委托的同步,异步,回调函数

    原文地址 同步调用 委托的Invoke方法用来进行同步调用.同步调用也可以叫阻塞调用,它将阻塞当前线程,然后执行调用,调用完毕后再继续向下进行. using System; using System. ...

  9. C#使用委托进行异步编程。

    首先引用MSDN中的一段话来描述一下如何使用异步方式.NET Framework 允许您异步调用任何方法. 为此,应定义与您要调用的方法具有相同签名的委托:公共语言运行时会自动使用适当的签名为该委托定 ...

随机推荐

  1. 【转】Jmeter做web压力测试时设置持续时间注意点

    头一回使用jmeter做web的压力测试,遇到个很莫名其妙的问题,不管我的线程组怎么设置,它就是执行一次就结束了. 设置循环次数为300,不使用调度器--〉执行一次就结束了,循环次数未生效 设置循环次 ...

  2. 怎样使用charles抓包

    本人因为是做前端的工作,需要后台写的一些数据,所以我需要一个神器能够抓到pc端或是移动端的后台数据,近期我发现一个神器“Charles”抓包神器. 需要操作的步骤如下: 1.先在网上下载Charles ...

  3. AJAX流程 代码

    var xml =      window.XMLHttpRequest ?new XMLHttpRequest() : new ActiveXObject("Microsoft.XMLHT ...

  4. mysql跟踪执行的sql语句

    修改my.cnf配置文件 /usr/local/mysql/bin/mysql --verbose --help | grep -A 1 'Default options' Default optio ...

  5. openstack resize 更新显卡驱动程序解决问题

  6. Android剖析和运行机制

    Android剖析和运行机制 大纲: 1. Android剖析 Linux内核本地库(Native Libraries)Android运行时(Android Runtime)应用框架 2. Andro ...

  7. 判断Android系统net和wap接入点的开发实例

    判断Android系统net和wap接入点的开发实例 分类标签: Activity   我们使用Android设备连接网络时,如果是wap接入点就需要设置代理,而电信和移动联通的代理并不相同,移动和联 ...

  8. 玩转Mysql命令

    连接数据库mysql -hlocalhost -uroot -p 在MYsql的跟目录文件下进行 show databses:展示所有数据库 解决方法1:在MySql安装目录下找到my.ini,将[m ...

  9. SpringCloud03 Ribbon知识点、 Feign知识点、利用RestTemplate+Ribbon调用远程服务提供的资源、利用feign调用远程服务提供的资源、熔断

    1 远程服务资源的调用 1.1 古老的套路 在微服务出现之前,所有的远程服务资源必须通过RestTemplate或者HttpClient进行:但是这两者仅仅实现了远程服务资源的调用,并未提供负载均衡实 ...

  10. 13-STL-二分查找

    STL中提供-二分查找算法(binary_search lower_bound upper_bound equal_range   STL包含四种不同的二分查找算法,binary_search    ...