使用委托实现同步回调与异步回调
使用委托可以执行的一项有用操作是实现回调。回调是传入函数的方法,在函数结束执行时调用该方法。
例如,有一个执行一系列数学操作的函数。在调用该函数时,也向其传递一个回调方法,从而在函数完成其计算工作时,调用回调方法,向用户通知计算结果。
同步回调
首先声明两个方法:
AddTwoNumbers():接受两个整型实参以及一个类型委托
ResultCallback():接受一个字符串,并显示出来。代码如下:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace DelegateCallBack
{
class Program
{
delegate void CallbackDelegate(string msg);
static void Main(string[] args)
{
//方式一:
CallbackDelegate result = ResultCallback;
AddTwoNumbers(5, 3, result);
//方式二:
AddTwoNumbers(5, 3, ResultCallback);
Console.Read();
}
static private void AddTwoNumbers(int num1,int num2,CallbackDelegate callback)
{
int result = num1 + num2;
callback(result.ToString());
}
static private void ResultCallback(string msg)
{
Console.WriteLine(msg);
}
}
}
异步回调
回调在异步情况下最有用。前面实例中说明的回调是同步回调,也就是按顺序调用函数。如果AddTwoNumbers方法花费较长时间来执行,则该函数之后的所有的语句将被阻塞。 组织较好的方式是异步调用AddTwoNumbers方法。异步调用函数允许主程序继续执行,而不需要等待该函数返回。 在这种异步模型中,当调用AddTwoNumbers函数时,在其后的语句继续执行。当函数结束时,他调用ResultCallback函数。
下面使用异步回调重写前面的程序:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Remoting.Messaging;
using System.Text;
using System.Threading.Tasks;
namespace DelegateCallBack
{
class Program
{
delegate int MethodDelegate(int num1, int num2);
static void Main(string[] args)
{
MethodDelegate result = AddTwoNumbers;
//引用异步操作完成时调用的方法
AsyncCallback callback = new AsyncCallback(ResultCallback);
Console.WriteLine("开始异步调用");
IAsyncResult iresult = result.BeginInvoke(5, 3, callback, null);
Console.WriteLine("主程序继续执行");
Console.Read();
}
static private int AddTwoNumbers(int num1,int num2)
{
int result = num1 + num2;
System.Threading.Thread.Sleep(5000);
return result;
}
static private void ResultCallback(IAsyncResult ar)
{
MethodDelegate dele = (MethodDelegate)((AsyncResult)ar).AsyncDelegate;
int result = dele.EndInvoke(ar);
Console.WriteLine("result={0}",result);
}
}
}
程序一运行:
五秒后
现在我们分析下程序,首先我们定义一个委托类型,从而可以指向AddTwoNumbers方法。
接下来,定义一个类型为AsyncCallback的委托。AsyncCallback是引用某个方法的委托,当异步操作完成时调用该方法。
使用result 委托的BeginInvoke()方法异步调用AddTwoNumbers(),并且向该方法传递两个整型以及在该方法结束执行时回调的委托。
BeginInvoke()方法异步调用委托,在调用异步委托之后,下一条语句会继续执行。该方法返回类型为IAsyncResult 的变量,该变量表示异步操作的状态。
在ResultCallback方法中,首先使用AsyncDelegate特性获得指向AddTwoNumbers()方法的委托,该特性返回进行异步调用的委托。接下来,使用EndInvoke()方法会的异步调用的结果,向该方法传递IAsycResult变量。
在使用异步回调时,可以通过在不同的线程中执行程序的不同部分来使程序更快速的响应。
- 洛谷 P3802 小魔女帕琪
- 【前沿】见人识面,TensorFlow实现人脸性别/年龄识别
- TensorFlow从0到1 - 1 - Hello, TensorFlow!
- iOS自动布局——Masonry详解
- BZOJ 3450: Tyvj1952 Easy
- [编程经验] TensorFlow实现线性支持向量机SVM
- TensorFlow从0到1 - 2 - TensorFlow核心编程
- BZOJ 4318: OSU!
- 讨厌算法的程序员 5 - 合并算法
- 洛谷 P2679 子串
- [编程经验] CVPR2017论文全集下载代码脚本分享
- 讨厌算法的程序员 6 - 归并排序
- [编程经验] Tensorflow中的共享变量机制小结
- 洛谷 P1313 计算系数
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- 从源码分析常见集合的区别之List接口
- c++ 调用ffmpeg命令获取视频属性
- Kubernetes 1.19.0——网络策略
- TypeScript 参数简化实战(进阶知识点conditional types,中高级必会)
- 最简实现Promise,支持异步链式调用(20行)
- 40行代码把Vue3的响应式集成进React做状态管理
- 写给女朋友的中级前端面试秘籍(含详细答案,15k级别)
- 写给初中级前端的高级进阶指南
- 为什么 Vue 中不要用 index 作为 key?(diff 算法详解)
- Vue3 的响应式和以前有什么区别,Proxy 无敌?
- 腾讯云TKE-PV使用cos存储案例: 容器目录权限问题
- Vue3 究竟好在哪里?(和 React Hook 的详细对比)
- 前端「N皇后」递归回溯经典问题图解
- 深入 TypeScript 中的子类型、逆变、协变,进阶 Vue3 源码前必须搞懂的。
- Vue3 + TypeScript 实现递归菜单组件