C# 同步调用 异步调用 异步回调 多线程的作用
同步调用 : 委托的Invoke方法用来进行同步调用。同步调用也可以叫阻塞调用,它将阻塞当前线程,然后执行调用,调用完毕后再继续向下进行。
异步调用 :同步调用会阻塞线程,如果是要调用一项繁重的工作(如大量IO操作),可能会让程序停顿很长时间,造成糟糕
的用户体验,这时候异步调用就很有必要了。
异步调用不阻塞线程,而是把调用塞到线程池中,程序主线程或UI线程可以继续执行。
委托的异步调用通过BeginInvoke和EndInvoke来实现。
异步回调函数 :当异步调用时,主线程并没有等待,而是直接向下运行了。
但是问题依然存在,当主线程运行到EndInvoke时,如果这时调用没有结束(这种情况很可能出现),这时为了等待调用结果,线程依旧会被阻塞。
解决的办法是用回调函数,当调用结束时会自动调用回调函数
同步调用程序实现
class Program
{
//同步调用
//委托的Invoke方法用来进行同步调用。同步调用也可以叫阻塞调用,它将阻塞当前线程,然后执行调用,调用完毕后再继续向下进行。
public delegate int AddHandler(int a,int b);//声明委托
static void Main(string[] args)
{
Console.WriteLine("*******(同步调用)SyncInvokeTest*******");
AddHandler handler = new AddHandler(Add);//定义委托,传入参数
int result = handler.Invoke(1, 2);//委托的同步调用,主线程执行到此时停止,即阻塞。调用同步调用委托的的方法,执行此方法。
Console.WriteLine("(继续做其他的事)Do other work.....");//other work 是指Add方法,进行两数相加操作。
Console.WriteLine(result);
Console.ReadLine();
}
private static int Add(int a, int b)//一个加法方法是一个线程
{
Console.WriteLine("Computing"+a+" + "+b+"...");
Thread.Sleep(9000);//模拟方法进行9秒
Console.WriteLine("computing complete.");
return a + b;
}
}
异步调用程序实现
class Program
{
//**************异步调用***********
//异步调用不阻塞线程,而是把调用塞到线程池中,程序主线程或UI线程可以继续执行。
//委托的异步调用通过BeginInvoke和EndInvoke来实现。
public delegate int AddHandler(int a,int b);
static void Main(string[] args)
{
Console.WriteLine("********(异步调用)AsyncInvokeTest******");
AddHandler handler = new AddHandler(Add);
IAsyncResult result = handler.BeginInvoke(1, 2, null, null);
Console.WriteLine("(继续做其他的事)do other work...");
Console.WriteLine(handler.EndInvoke(result));
Console.ReadLine();
}
private static int Add(int a, int b)
{
Console.WriteLine("computing "+a+"+"+b+"....");
Thread.Sleep(9000);//模拟方法进行9秒
Console.WriteLine("computing complete");
return a + b;
}
}
异步调用加入回调函数程序实现
class Program
{
//**************异步回调***********
//用回调函数,当调用结束时会自动调用回调函数,解决了为等待调用结果,而让线程依旧被阻塞的局面。
//注意: BeginInvoke和EndInvoke必须成对调用.即使不需要返回值,但EndInvoke还是必须调用,否则可能会造成内存泄漏。
public delegate int AddHandler(int a, int b);
static void Main(string[] args)
{
Console.WriteLine("********(异步回调调用)AsyncInvokeTest******");
AddHandler handler = new AddHandler(Add);
IAsyncResult result = handler.BeginInvoke(1, 2, new AsyncCallback(AddComplete),"AsycState:OK");
Console.WriteLine("(继续做其他的事)do other work...");
// Console.WriteLine(handler.EndInvoke(result));//对于每个异步操作只能调用一次EndInvoke()方法。
Console.ReadLine();
}
private static int Add(int a, int b)
{
Console.WriteLine("computing " + a + "+" + b + "....");
Thread.Sleep(3000);//模拟方法进行9秒
Console.WriteLine("computing complete");
return a + b;
}
static void AddComplete(IAsyncResult result)//异步回调函数
{
AddHandler handler = (AddHandler) ((AsyncResult) result).AsyncDelegate;
Console.WriteLine(handler.EndInvoke(result));
Console.WriteLine(result.AsyncState);
}
//异步委托,也可以参考如下写法:
//Action<object> action=(obj)=>method(obj);
//action.BeginInvoke(obj,ar=>action.EndInvoke(ar),null);
//简简单单两句话就可以完成一部操作。
}
多线程是为了提高用户体验,解决窗体界面假死状态的好的选择。同步线程是阻塞线程,对提高用户体验和界面假死没什么帮助。异步线程才可以提高程序的性能,和用户体验。平时说的多线程是指异步线程。
C# 同步调用 异步调用 异步回调 多线程的作用的更多相关文章
- C#(同步调用、异步调用、异步回调)
Review: 原作者虽然使用了汉字的类名,看起来十分蹩脚,但是,还是把同步调用.异步调用.异步回调的使用讲解的很详细的.原理讲解的很清晰. ------ 本文将主要通过“同步调用”.“异步调用”.“ ...
- java常见的几种调用机制(同步调用,异步调用,回调)
1.同步调用 同步调用是最基本的调用方式,对象b中的方法直接调用对象a的方法,这个时候程序会等待对象a的方法执行完返回结果之后才会继续往下走. 代码如下: public class A {public ...
- Python并发编程06 /阻塞、异步调用/同步调用、异步回调函数、线程queue、事件event、协程
Python并发编程06 /阻塞.异步调用/同步调用.异步回调函数.线程queue.事件event.协程 目录 Python并发编程06 /阻塞.异步调用/同步调用.异步回调函数.线程queue.事件 ...
- 委托(delegate)的三种调用方式:同步调用,异步调用,异步回调(转载)
下面为即将被调用的方法: public delegate int AddHandler(int a,int b); public class 加法类 { public static int Add(i ...
- java三种调用方式(同步调用/回调/异步调用)
1:同步调用:一种阻塞式调用,调用方要等待对方执行完毕才返回,它是一种单向调用 2:回调:一种双向调用模式,也就是说,被调用方在接口被调用时也会调用对方的接口: 3:异步调用:一种类似消息或事件的机制 ...
- C#“同步调用”、“异步调用”、“异步回调”
本文将主要通过“同步调用”.“异步调用”.“异步回调”三个示例来讲解在用委托执行同一个“加法类”的时候的的区别和利弊. 首先,通过代码定义一个委托和下面三个示例将要调用的方法: ); //模拟该方法运 ...
- 整理 C#(同步调用、异步调用、异步回调)
//闲来无事,巩固同步异步方面的知识,以备后用,特整理如下: class Program { static void Main(string[] args) { //同步调用 会阻塞当前线程,一步一步 ...
- C# 委托的三种调用示例(同步调用 异步调用 异步回调)
首先,通过代码定义一个委托和下面三个示例将要调用的方法: 复制代码 代码如下: public delegate int AddHandler(int a,int b); public class ...
- 用delegate实现.NET应用程序的同步函数的异步调用-.NET多线程编程实践之一
在C++中有2种类型的线程:UI Thread和Worker Thread,前者是基于用户界面的有消息循环的线程.后者是没有用户界面的侧重于大时空运算的线程.直接调用Windows相关线程及同步对象的 ...
随机推荐
- hdu 6206 : Apple 【计算几何 + 分数类】
题目链接 比赛时C++上__float128都被卡精度,然后扔给队友用Java的BigDecimal过了 算法不多说,求三角形外心可以参考 维基百科 https://zh.wikipedia.org/ ...
- C++的命令行参数(gflag)
参考:https://www.cnblogs.com/myyan/p/4699940.html 这是一款google开源的命令行参数解析工具,支持从环境变量.配置文件读取参数(可以用gflags代替配 ...
- 洛谷 P2590 BZOJ 1036 [ZJOI2008]树的统计
Time limit 10000 ms//另外,BZOJ只算所有点的总时限,所以可能会放过一些原本会TLE的代码 Memory limit 165888 kB OS Linux SourceZJOI2 ...
- 【bzoj3566】 [SHOI2014]概率充电器
*题目描述: 著名的电子产品品牌 SHOI 刚刚发布了引领世界潮流的下一代电子产品——概率充电器: “采用全新纳米级加工技术,实现元件与导线能否通电完全由真随机数决定!SHOI 概率充电器,您生活不可 ...
- EF 查询时,返回其中一张表(省掉一个个写字段的麻烦)
1.使用partial将需要添加的字段进行扩展 public partial class T_OrderInfo { public string EntName { get; set; } } 2.使 ...
- EQS 自定义Context 如何用Testing Pawn 进行测试?
比如自定义了一个玩家的Context, 那么需要把这个玩家直接放置到场景中 在Context中override Provide Single Actor函数,按类型获取所有的Actor,其中第一个作为 ...
- D1. Kirk and a Binary String (easy version)
D1. Kirk and a Binary String (easy version) 01串找最长不降子序列 给定字符串s,要求生成一个等长字符串t,使得任意l到r位置的最长不降子序列长度一致 从后 ...
- 如何将一个SpringBoot简便地打成一个war包(亲测有效)
正常情况下SpringBoot项目是以jar包的形式,通过命令行: 来运行的,并且SpringBoot是内嵌Tomcat服务器,所以每次重新启动都是用的新的Tomcat服务器.正因如此,也出现了一个问 ...
- MacOS下Java Mission Control无法正常启动
参考JMC(Java Mission Control)在mac下无法启动和显示界面 附件下载地址备份(org.eclipse.swt.cocoa.macosx.x86_64-3.112.0.jar) ...
- 回望2017,基于深度学习的NLP研究大盘点
回望2017,基于深度学习的NLP研究大盘点 雷锋网 百家号01-0110:31 雷锋网 AI 科技评论按:本文是一篇发布于 tryolabs 的文章,作者 Javier Couto 针对 2017 ...