• C# 方法的回调(上)


    在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 0;      
    }

    执行结果:

    敲击任意键显示当前时间,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 = 0;
    }
    
    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, 0, 1000);
               Console.ReadKey();
               tm.Dispose();
            }
    }    

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

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

  • 相关阅读:
    解决magento后台无法登陆/登陆没有反应的方法
    修正magento快速搜索返回结果不准确
    怎么在手机浏览器上访问电脑本地的文件,局域网内,自建WiFi也可以
    php中cookie+mysql实现的购物车代码
    深入分析Php处理浮点数的问题
    Ecshop安装过程中的的问题:cls_image::gd_version()和不支持JPEG
    推荐mysql优化的21条经验
    Magento产品批量导入方法?
    Magento控制器
    grub uuid设置
  • 原文地址:https://www.cnblogs.com/MrALei/p/4718408.html
Copyright © 2020-2023  润新知