• 博客园logo
  • 会员
  • 众包
  • 新闻
  • 博问
  • 闪存
  • 赞助商
  • HarmonyOS
  • Chat2DB
    • 搜索
      所有博客
    • 搜索
      当前博客
  • 写随笔 我的博客 短消息 简洁模式
    用户头像
    我的博客 我的园子 账号设置 会员中心 简洁模式 ... 退出登录
    注册 登录
jk-2048
博客园    首页    新随笔    联系   管理    订阅  订阅
刘铁猛C#学习笔记14 委托2-回调方法、委托高级使用

示例:回调方法

(也称作好莱坞方法)
演员去面试,给导演留了名片
导演说如果选中他,会给他打电话的
using System;

namespace CallBack
{
    class Program
    {
        static void Main(string[] args)
        {
            //创建工厂实例
            ProductFactory productFactory = new ProductFactory();  //创建产品工厂的实例
            WrapFactory wrapFactory = new WrapFactory();  //创建包装工厂的实例

            //用委托封装生产产品的方法
            Func<Product> func1 = new Func<Product>(productFactory.MakePizza);
            //创建委托1,用来封装产品工厂类中生产披萨的方法
            Func<Product> func2 = new Func<Product>(productFactory.MakeToyCar);
            //创建委托1,用来封装产品工厂类中生产小汽车的方法

            Logger logger = new Logger();  //创建记录者类的实例
            Action<Product> log = new Action<Product>(logger.Log); //

            //使用模板方法
            Box box1 = wrapFactory.WrapProduct(func1,log);  //使用模板方法,生产并包装披萨
            Box box2 = wrapFactory.WrapProduct(func2,log);  //使用模板方法,生产并包装小汽车

            //将生产与包装分为两个过程,降低耦合度,最大限度提高代码复用率(复用了包装逻辑)

            //这样当一个产品的生产程序出问题时,不会干扰其他产品的生产和包装
            //需要维护一个产品的生产程序时,也不需要动其他产品的生产和包装程序
            //提高维护性、可扩展性

        }
    }

    class Logger  //记录程序的运行状态的类,实际开发工程中一般都会有这个类
    {
        public void Log(Product product)  //输出产品状态的方法
        {
            Console.WriteLine("Produict '{0}' creaded at {1}. Price is {2}.", product.Name, DateTime.UtcNow, product.Price);
        }
    }


    class Product  //产品类
    {
        public string Name { get; set; }   //产品成员字段:产品的名字
        public double  Price { get; set; }  //产品的价格

    }

    class Box  //包装箱
    {
        public Product Product { get; set; } //箱子里包装的产品
    }

    class WrapFactory   //盒子工厂类,用来生产盒子并将产品装入
    {
        public Box WrapProduct(Func<Product> getProduct,Action<Product> logCallback)   

        {           //< >中表示作为参数的委托的返回值类型是Product
               //模板方法,把产品包上盒子交给用户   回调方法logCallback:显示产品当前状态
            Box box = new Box();              //创建一个新盒子
            Product product = getProduct.Invoke();  //从委托参数中拿到传进来的产品对象

            if(product.Price >= 50)  //是否使用回调方法的判断
            {
                logCallback(product);   //若价格大于50元,使用回调方法,输出产品信息
            }

            box.Product = product;   //将产品塞进盒子里
            return box;  //返回包装好产品的盒子

        }

    }

    class ProductFactory   //产品工厂类,用来生产产品,内含多种不同的产品生产方法
    {
        public Product MakePizza()  //用来生产披萨产品
        {
            Product product = new Product();
            product.Name = "Pizza";   //将产品实例的字段填为Pizza
            product.Price = 12;       //披萨价格12元
            return product;
        }

        public Product MakeToyCar()  //用来生产玩具小汽车产品
        {
            Product product = new Product();
            product.Name = "Toy Car";   //将产品实例的字段填为Toy Car
            product.Price = 100;        //小汽车价格100元
            return product;
        }
    }
}

委托的高级使用

1.多播委托

首先添加一个与多线程相关的命名空间的引用
然后声明一个类,有两个属性
3名学生分别用不同颜色的笔写作业,通过委托简介调用方法
结果:3位学生依次完成了作业
 
合并委托
将action2和action3都合并进action1,现在action1内就封装了3个方法
然后执行,得到的结果与之前一样
这样一个委托封装多个方法的使用方法叫多播委托
委托中方法的执行顺序按照其封装进方法的先后顺序,先被丢进委托的先执行
 

2.隐式异步调用EX

同义名词解释

串行 = 同步 = 单线程, 并行 = 异步 = 多线程

1.进程与线程

两项工作同时进行
每一个程序都是一个进程(process)
每一个进程可以有多个线程(thread)

2.同步调用

单线程调用方法,是前一个方法执行完毕,后一个方法才能开始执行
结果是按顺序依次执行,最后执行主线程

3.异步调用

同时执行,各方法线程互不相干,一个方法的开始和结束不会影响另一个线程的开始和结束

4.使用委托的隐式异步调用

使用委托的BeginInvoke方法
两个参数:第一个是异步调用的回调(callback)
结果:主线程与3个分支线程并行执行
第三行和第四行颜色相同原因:
各线程都在调用控制台的前景色这个属性,当多个线程异步访问同一个资源时,可能会因为争抢资源发生冲突,产生这样的错误情况
需要线程加锁等方法避免多线程程序中的资源冲突(待续)
 

5.显式异步调用

(1)Thread(一种古老方式)

也是各线程独立执行,也发生来了资源争抢
 

(2)Task

需要引用这个子命名空间
也是各自独立运行,也有资源争抢
 
编程常识:
JAVA没有委托,完全用接口,但也活地好好的
 
posted on 2024-02-23 23:19  JK降谷羽  阅读(111)  评论(0)    收藏  举报
刷新页面返回顶部
博客园  ©  2004-2025
浙公网安备 33010602011771号 浙ICP备2021040463号-3