在C#编程中方法的回调有以下几种方式

通过接口、通过委托、定时回调、多线程回调,异步回调

下面就以代码的形式来讲解这种方式

通过接口回调

代码示例如下

定义接口,定义了一个Run 方法:

interface ICallBack
{
void Run();
}

定义实现接口的类,并实现接口中定义的方法,方法的作用就是输出当前时间:

class CallBackClass:ICallBack
{
public void Run()
{
Console.WriteLine(DateTime.Now);
}
}

定义“控制回调器“类,定义一个接口类型的字段,用于引用回调对象。定义一个ByInterface方法,用于执行回调:

class Controller
{
//接口回调
private readonly ICallBack _callBackObject = null; public Controller(ICallBack obj)
{
this._callBackObject = obj;
} public void ByInterface()
{
Console.WriteLine("敲击任意键显示当前时间,ESC键退出...");
while (Console.ReadKey(true).Key != ConsoleKey.Escape)
{
this._callBackObject.Run();
}
}
}

在Main方法中执行:

static int Main(string[] args)
{
Controller controller = new Controller(new CallBackClass());
controller.ByInterface(); return ;
}

执行结果:

敲击任意键显示当前时间,ESC键退出...

2015/08/10 16:03:22
2015/08/10 16:03:22
2015/08/10 16:03:23
2015/08/10 16:03:23
2015/08/10 16:03:23

大家对于在Controller类中ICallBack接口变量的使用有什么看法?

我觉得在控制回调器中用接口类型做字段,无疑会降低类与类之间的耦合度,不局限于某一特定的类,只要是实现了接口的对象都可以被调用,这样的程序设计才是被提倡的。

通过委托实现回调

关于委托有这样一句话:.NET 来通过委托提供了一种回调函数机制

所以说使用委托实现回调是最直截了当的的方式了,下面是代码示例。

控制回调器类代码

class Controller
{ //定义一个委托类型的字段
private Action showTime = null;

  //构造函数内接收外界提供的方法
public Controller(Action showTime)
{
this.showTime += showTime;
} public void ByDelegate()
{
Console.WriteLine("敲击任意键显示当前时间,ESC键退出...");
while (Console.ReadKey(true).Key != ConsoleKey.Escape)
{
this.showTime();
}
}
}

在Main方法中执行:

static int Main(string[] args)
{
Controller controller = new Controller(new Action(()=>Console.WriteLine(DateTime.Now)));
controller.ByDelegate();
}

执行结果和通过接口回调的示例一样,在此就不展示结果了

上述代码中的红字为lambda表达式写的匿名方法;

由于委托允许动态的添加(+=)和移除(-=)回调方法,所以比接口使用起来更加灵活

通过定时回调

这种方式应用场景比较特殊,需要以固定的时间间隔调用某个方法。

利用了.NET Framework提供的Timer类,定时回调一个满足TimerCallBack委托要求的方法,此委托定义如下:

public delegate void TimerCallback(object state);

该委托定义了一个object类型参数的方法 Timer类构造函数如下:

public Timer(TimerCallback callback, object state, int dueTime, int period)

参数解析:

callback:定时回调的方法

state:向回调方法传递的参数

dueTime:开发执行回调方法之前延迟的时间,单位是秒。设为0为立即调用回调方法

period:执行回调方法的间隔秒数

示例如下:

public class TaskInfo
{
public int Count = ;
} static class Program
{
static void Main()
{
var ti=new TaskInfo();
var tm = new Timer(
  obj => {
var taskInfo = obj as TaskInfo;
taskInfo.Count++
;
Console.WriteLine(taskInfo.Count);
}

, ti, , );
Console.ReadKey();
tm.Dispose();
}
}

上述代码中红字为匿名函数,使用了lambda表达式。

关于多线程回调和异步回调下篇再续~谢谢

C# 方法的回调(上)的更多相关文章

  1. array_reduce方法用回调函数迭代地将对数组的值进行操作

    在处理php数组的时候,有一种需求特别的频繁,如下二维数组: $arr = array( 1=>array( 'id' => 5, 'name' => '张三' ), 2=>a ...

  2. JNI-Thread中start方法的调用与run方法的回调分析

    前言 在java编程中,线程Thread是我们经常使用的类.那么创建一个Thread的本质究竟是什么,本文就此问题作一个探索. 内容主要分为以下几个部分 1.JNI机制的使用 2.Thread创建线程 ...

  3. JavaScript 使用 sort() 方法从数值上对数组进行排序

    使用 sort() 方法从数值上对数组进行排序. <html> <body> <script type="text/javascript"> f ...

  4. php函数实现显示几秒前,几分钟前,几天前等方法(网络上什么都有)

    php函数实现显示几秒前,几分钟前,几天前等方法(网络上什么都有) 一.总结 网络上面什么函数都有 二.php函数实现显示几秒前,几分钟前,几天前等方法 现在很多网站的时间显示都很人性化,不再是单纯的 ...

  5. js数组方法大全(上)

    # js数组方法大全(上) 记录一下整理的js数组方法,免得每次要找方法都找不到.图片有点多,注意流量,嘻嘻! 本期分享 join() reverse() sort() concat() slice( ...

  6. ajax中的post方法中回调函数不执行的问题

    前一段时间接触了JQuery Ajax中的.post()方法和.get()方法,感觉到ajax的简洁和强大,当用到.post()方法时,去W3上查找相关的使用方法,感觉十分简单,用法很明了,然后,直接 ...

  7. FullPage.js全屏滚动插件的配置项、方法和回调函数

    fullPage.js 是一个基于 jQuery 的插件,它能够很方便.很轻松的制作出全屏网站,主要功能有: 支持鼠标滚动 支持前进后退和键盘控制 多个回调函数 支持手机.平板触摸事件 支持 CSS3 ...

  8. 利用jquery.form.js实现将form提交转为ajax方式提交的方法(带上传的表单提交)

    提供一种方法就是利用jquery.form.js. (1)这个框架集合form提交.验证.上传的功能. 核心方法 -- ajaxForm() 和 ajaxSubmit() $('#myForm').a ...

  9. XHR 对象实例所有的配置、属性、方法、回调和不可变值

    当我们声明了一个XMLHttpRequest对象的实例的时候,使用for-in来循环遍历一下这个实例(本文使用的是chrome45版本浏览器),我们会发现在这个实例上绑定了一些内容,我把这些内容进行了 ...

随机推荐

  1. UVa2326

    理解:区域覆盖.注意1,属于的区间有大小颠倒的情况:注意2,看图 ,两排房间公用一条走廊(for instance 1->3  4->6 不可公用) #include<iostrea ...

  2. embed标签loop=true背景音乐无法循环

    在html网页中加入背景音乐并设置为循环播放.一开始用<embed>标签,设置loop="true", 但是结果发现在IE浏览器可以,但是在chrome浏览器却无法实现 ...

  3. 【分享】SQL中的注入漏洞

    例:假设一个账户密码的输入在数据库中是这样进行判断的. ' ) AS PWDCORRECT FROM T_USER WHERE FUSER= 'GUEST' 如果输入: ') AS PWDCORREC ...

  4. Java 网络编程之 Socket

    ========================UDP============================= UDP---用户数据报协议,是一个简单的面向数据报的运输层协议. UDP不提供可靠性, ...

  5. Android编程容易犯的错误之二

    11.不要太相信工具,比如Eclipse里面的断点遇到多线程什么,经常不起作用/走不到,还有就是如果语句为空的也不会走,这时候别太早下结论断点地方出错了, 所以每个工程都应该有日志的开关,通过查看日志 ...

  6. Java内部类详解

    Java内部类详解 说起内部类这个词,想必很多人都不陌生,但是又会觉得不熟悉.原因是平时编写代码时可能用到的场景不多,用得最多的是在有事件监听的情况下,并且即使用到也很少去总结内部类的用法.今天我们就 ...

  7. 【学习笔记】ionic 学习之环境搭建

    初学ionic ,后面会把学习的点滴和踩到坑全部记录下来 1.环境 安装node.js 官网地址:https://nodejs.org/en/ 下载安装包安装.自己记住自己的安装路径哦 安装完成后我们 ...

  8. whose view is not in the window hierarchy

    参考:http://www.jianshu.com/p/9e90cb866fdf 在做界面跳转的时候,我们经常会用到这两个函数 func dismissViewControllerAnimated(f ...

  9. ThinkPHP动态版本控制

    动态版本控制可以根据时间戳来实现,但是这样的话,每次打开页面都会重新下载加了版本控制的文件,如果你的页面自身打开本来就慢的话, 这样一来,无疑会带来很差的用户体验. 但是如果在每个引用文件后面都手动加 ...

  10. SASS 编译后去掉缓存文件和map文件

    编译的时候加参数 --sourcemap=none --no-cache 就可以了