一.委托的同步和异步:

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. JDK 8 - Lambda Expression 的优点与限制

    我们知道 JDK 8 新增了 Lambda Expression 这一特性. JDK 8 为什么要新增这个特性呢? 这个特性给 JDK 8 带来了什么好处? 它可以做什么?不可以做什么? 在这篇文章, ...

  2. TCP之四:TCP 滑动窗口协议 详解

    滑动窗口机制 滑动窗口协议的基本原理就是在任意时刻,发送方都维持了一个连续的允许发送的帧的序号,称为发送窗口:同时,接收方也维持了一个连续的允许接收的帧的序号,称为接收窗口.发送窗口和接收窗口的序号的 ...

  3. Kali终端美化

    首先安装figlet和cowsay root@sch01ar:~# apt-get install figlet root@sch01ar:~# apt-get install cowsay 用lea ...

  4. Command对象

  5. python 模块 optparse

    optparse,是一个能够让程式设计人员轻松设计出简单明了.易于使用.符合标准的Unix命令列程式的Python模块.生成使用和帮助信息. 下面是一个简单的示例: import optparse p ...

  6. ZooKeeper集群搭建过程

    ZooKeeper集群搭建过程 提纲 1.ZooKeeper简介 2.ZooKeeper的下载和安装 3.部署3个节点的ZK伪分布式集群 3.1.解压ZooKeeper安装包 3.2.为每个节点建立d ...

  7. 24-从零玩转JavaWeb-包装类、自动装箱、自动拆箱

    一.什么是包装类 二.对基本数据类型包装的好处 三.装箱操作 四.拆箱操作 五.自动装箱 六.自动拆箱 七.字符串与基本数据类型和包装类的转换   八.包装类的缓存设计

  8. Java基础知识(二)之控制语句

    1.条件运算符   ⑴if...else... ⑵三目表达式——X?Y:Z 当X为真时,结果为Y:反之,为Z. ⑶switch(表达式){ case 1:    执行代码块 1; break: cas ...

  9. java中链表的数据(对象)位置交换

    用LinkedList类的set方法把引用 对象换了就行 ,如 import java.util.LinkedList; public class Tffdsafsdafsad { public st ...

  10. Solidity 没名字的function(){...}作用

    官方解释: 这个叫做fallback function,当有人 1. 只发送以太币给合约而不带任何输入数据:2. 调用smart contract时调起了一个不存在的方法.会触发执行这个方法. Wha ...