• c#学习-(委托的高级使用)


    一、多播委托(multicast)&& 单播委托

            一个委托内部封装不止一个方法

    1. using System;
    2. using System.Collections.Generic;
    3. using System.Linq;
    4. using System.Text;
    5. using System.Threading.Tasks;
    6. using System.Threading;
    7. namespace six_multicast
    8. {
    9. internal class Program
    10. {
    11. static void Main(string[] args)
    12. {
    13. Student student = new Student() { Id=1,PenColor = ConsoleColor.Yellow};
    14. Student student2 = new Student() { Id = 2,PenColor = ConsoleColor.Red};
    15. Student student3 = new Student() { Id = 3, PenColor = ConsoleColor.Green };
    16. Action action1 = new Action(student.DoHomeWork);
    17. Action action2 = new Action(student2.DoHomeWork);
    18. Action action3 = new Action(student3.DoHomeWork);
    19. //单播
    20. action1.Invoke();
    21. action2.Invoke();
    22. action3.Invoke();
    23. //多播
    24. action1 += action2;
    25. action1 += action3;
    26. action1.Invoke();
    27. }
    28. }
    29. class Student
    30. {
    31. public int Id { get; set; }
    32. public ConsoleColor PenColor { get; set; }
    33. public void DoHomeWork()
    34. {
    35. for (int i = 0; i < 5; i++)
    36. {
    37. Console.ForegroundColor = this.PenColor;
    38. Console.WriteLine("Student is {0} do homework {1} hour(s)", this.Id, i);
    39. Thread.Sleep(1000);
    40. }
    41. }
    42. }
    43. }

    二、同步调用

    每一个允许的程序是一个进程(Process)

    每个进程可以有多个线程(Thread)

    同步调用是在一个线程里

    串行==同步==单线程

    同步调用三种形式

            1、直接同步调用

            2、单播委托的间接调用

            3、多播委托的间接调用

    1. using System;
    2. using System.Collections.Generic;
    3. using System.Linq;
    4. using System.Text;
    5. using System.Threading.Tasks;
    6. using System.Threading;
    7. namespace six_multicast
    8. {
    9. internal class Program
    10. {
    11. static void Main(string[] args)
    12. {
    13. Student student = new Student() { Id=1,PenColor = ConsoleColor.Yellow};
    14. Student student2 = new Student() { Id = 2,PenColor = ConsoleColor.Red};
    15. Student student3 = new Student() { Id = 3, PenColor = ConsoleColor.Green };
    16. Action action1 = new Action(student.DoHomeWork);
    17. Action action2 = new Action(student2.DoHomeWork);
    18. Action action3 = new Action(student3.DoHomeWork);
    19. //同步调用
    20. //在一根主线程上面执行(创建对象),当有方法执行的时候就去执行方法,然后继续执行主线程,最后主线程还有些事情要做
    21. //直接调用
    22. student.DoHomeWork();
    23. student2.DoHomeWork();
    24. student3.DoHomeWork();
    25. //单播(单波委托的间接调用)
    26. action1.Invoke();
    27. action2.Invoke();
    28. action3.Invoke();
    29. //多播(多播委托的间接调用)
    30. action1 += action2;
    31. action1 += action3;
    32. action1.Invoke();
    33. for (int i = 0; i < 10; i++)
    34. {
    35. Console.ForegroundColor = ConsoleColor.Cyan;
    36. Console.WriteLine("Main thread {0}", i);
    37. Thread.Sleep(1000);
    38. }
    39. }
    40. }
    41. class Student
    42. {
    43. public int Id { get; set; }
    44. public ConsoleColor PenColor { get; set; }
    45. public void DoHomeWork()
    46. {
    47. for (int i = 0; i < 5; i++)
    48. {
    49. Console.ForegroundColor = this.PenColor;
    50. Console.WriteLine("Student is {0} do homework {1} hour(s)", this.Id, i);
    51. Thread.Sleep(1000);
    52. }
    53. }
    54. }
    55. }

    三、异步调用

    同时进行,多个线程,底层原理=多线程

    并行=异步=多线程

    1. using System;
    2. using System.Collections.Generic;
    3. using System.Linq;
    4. using System.Text;
    5. using System.Threading.Tasks;
    6. using System.Threading;
    7. namespace six_multicast
    8. {
    9. internal class Program
    10. {
    11. static void Main(string[] args)
    12. {
    13. Student student = new Student() { Id=1,PenColor = ConsoleColor.Yellow};
    14. Student student2 = new Student() { Id = 2,PenColor = ConsoleColor.Red};
    15. Student student3 = new Student() { Id = 3, PenColor = ConsoleColor.Green };
    16. Action action1 = new Action(student.DoHomeWork);
    17. Action action2 = new Action(student2.DoHomeWork);
    18. Action action3 = new Action(student3.DoHomeWork);
    19. //异步调用(多个线程争抢一个资源,会起冲突)
    20. //显示异步掉用(老方式)
    21. Thread thread = new Thread(new ThreadStart(student.DoHomeWork));
    22. Thread thread2 = new Thread(new ThreadStart(student2.DoHomeWork));
    23. Thread thread3 = new Thread(new ThreadStart(student3.DoHomeWork));
    24. thread.Start();
    25. thread2.Start();
    26. thread3.Start();
    27. //显示异步调用(新方式)
    28. Task task = new Task(new Action(student.DoHomeWork));
    29. Task task1 = new Task(new Action(student2.DoHomeWork));
    30. Task task2 = new Task(new Action(student3.DoHomeWork));
    31. task.Start();
    32. task1.Start();
    33. task2.Start();
    34. //隐式异步调用
    35. action1.BeginInvoke(null, null);
    36. action2.BeginInvoke(null, null);
    37. action3.BeginInvoke(null, null);
    38. for (int i = 0; i < 10; i++)
    39. {
    40. Console.ForegroundColor = ConsoleColor.Cyan;
    41. Console.WriteLine("Main thread {0}", i);
    42. Thread.Sleep(1000);
    43. }
    44. }
    45. }
    46. class Student
    47. {
    48. public int Id { get; set; }
    49. public ConsoleColor PenColor { get; set; }
    50. public void DoHomeWork()
    51. {
    52. for (int i = 0; i < 5; i++)
    53. {
    54. Console.ForegroundColor = this.PenColor;
    55. Console.WriteLine("Student is {0} do homework {1} hour(s)", this.Id, i);
    56. Thread.Sleep(1000);
    57. }
    58. }
    59. }
    60. }

    总结:

            应该慎重的使用委托

            对于为什么会造成内存泄漏和程序性能下降原因

            委托会引用一个方法,这个方法如果是一个实例方法的话,那么这个方法必定会隶属于一个对象,你拿一个委托引用了这个方法,那么这个对象就必须存在于内存当中,即便是没有其他的引用变量引用这个对象,因为你一释放这个内存,委托就不能够间接去调用对象的方法,所以所委托有可能造成内存泄漏,随着泄漏的内存越来越多,程序就会崩溃

            使用异步会导致出现多个线程争抢资源的情况,会出现冲突,可以加上线程锁,另外,应该合适的使用接口interface取代一些对委托的使用

            下面两个分别是使用接口interface与使用委托delegate,最终的实现都是一样

            

    1. using System;
    2. using System.Collections.Generic;
    3. using System.Linq;
    4. using System.Text;
    5. using System.Threading.Tasks;
    6. namespace six_InterfaceDelegate
    7. {
    8. internal class Program
    9. {
    10. static void Main(string[] args)
    11. {
    12. WrapFactory wrapFactory = new WrapFactory();
    13. IProductFactory MakePizza = new MakePizza();
    14. IProductFactory MakeCar = new MakeCar();
    15. Box box = wrapFactory.ProductFactory(MakePizza);
    16. Box box2 = wrapFactory.ProductFactory(MakeCar);
    17. Console.WriteLine(box.Product.Name);
    18. Console.WriteLine(box2.Product.Name);
    19. }
    20. }
    21. interface IProductFactory
    22. {
    23. Product Make();
    24. }
    25. class MakePizza : IProductFactory
    26. {
    27. public Product Make()
    28. {
    29. Product product = new Product();
    30. product.Name = "Pizza";
    31. return product;
    32. }
    33. }
    34. class MakeCar : IProductFactory
    35. {
    36. public Product Make()
    37. {
    38. Product product = new Product();
    39. product.Name = "Car";
    40. return product;
    41. }
    42. }
    43. class Product
    44. {
    45. public string Name { get; set; }
    46. }
    47. class Box
    48. {
    49. public Product Product { get; set; }
    50. }
    51. class WrapFactory
    52. {
    53. public Box ProductFactory(IProductFactory productFactory)
    54. {
    55. Box box = new Box();
    56. Product product = productFactory.Make();
    57. box.Product = product;
    58. return box;
    59. }
    60. }
    61. }
    1. using System;
    2. using System.Collections.Generic;
    3. using System.Linq;
    4. using System.Text;
    5. using System.Threading.Tasks;
    6. /*
    7. 演示了如何使用委托和模板方法来包装产品
    8. */
    9. namespace four_GreateDelegate2
    10. {
    11. internal class Program
    12. {
    13. static void Main(string[] args)
    14. {
    15. ProductFactory productFactory = new ProductFactory();
    16. WrapFactory wrapFactory = new WrapFactory();
    17. Func func1 = new Func(productFactory.MakePizza);
    18. Func func2 = new Func(productFactory.MakeToCar);
    19. Box box1 = wrapFactory.WrapProduct(func1);
    20. Box box2 = wrapFactory.WrapProduct(func2);
    21. Console.WriteLine(box1.Product.Name);
    22. Console.WriteLine(box2.Product.Name);
    23. }
    24. }
    25. class Product//产品
    26. {
    27. public string Name { get; set; }
    28. }
    29. class Box//箱子
    30. {
    31. public Product Product { get; set; }
    32. }
    33. class WrapFactory
    34. {
    35. public Box WrapProduct(Func getProduct)
    36. {
    37. Box box = new Box();
    38. Product product = getProduct.Invoke();
    39. box.Product = product;
    40. return box;
    41. }
    42. }
    43. class ProductFactory
    44. {
    45. public Product MakePizza()
    46. {
    47. Product product = new Product();
    48. product.Name = "Pizza";
    49. return product;
    50. }
    51. public Product MakeToCar()
    52. {
    53. Product product = new Product();
    54. product.Name = "Toy Car";
    55. return product ;
    56. }
    57. }
    58. }

  • 相关阅读:
    清华训练营悟道篇之操作系统的调用接口
    Blazor前后端框架Known-V1.2.14
    年产10万吨环氧树脂车间工艺设计
    SDN落地场景
    mysql启动不了问题
    dependencies
    敏捷技巧:产品经理的需求文档应该写成什么样才算合格?
    金仓数据库 KingbaseGIS 使用手册(6.21. 长事务支持)
    linux安裝maven
    从零开始:PHP实现阿里云直播的简单方法!
  • 原文地址:https://blog.csdn.net/weixin_66365687/article/details/139395878