zoukankan      html  css  js  c++  java
  • 异步编程:利用委托实现的.NET历史上第一个异步编程模型

    同步:前面的做完了,才轮到我来做;

    同步示意

    异步:同一时间各做各的,互不干扰;相当于我们生活中常说的"同步"

    异步示意

    方法的同步调用与异步调用:

    • 程序运行起来就会创建一个进程;
    • 一个进程中可以有多个线程;
    • 同步调用是指在一个线程中,顺次执行;
    • 异步调用需要依靠多线程;
    • 同步、串行、单线程 指的是一个意思;
    • 异步、并行、多线程 指的是一个意思;
      同步和异步的区别

    使用方法名,直接同步调用

    class Program
    {
        static void Main(string[] args)
        {
            //方法的直接调用就是一种同步执行--执行完一个再执行下一个
            Dog dog1 = new Dog() { DogName = "嘟嘟", ConsoleColor = ConsoleColor.Red };
            dog1.WangWang();
            Console.WriteLine(dog1.DogName+"汪汪叫完毕");
            Thread.Sleep(TimeSpan.FromSeconds(0.5));
            Dog dog2 = new Dog() { DogName = "壮壮", ConsoleColor = ConsoleColor.Green };
            dog2.WangWang();
            Console.WriteLine(dog2.DogName + "汪汪叫完毕");
            Thread.Sleep(TimeSpan.FromSeconds(0.5));
            Dog dog3 = new Dog() { DogName = "小强", ConsoleColor = ConsoleColor.Yellow };
            dog3.WangWang();
            Console.WriteLine(dog3.DogName + "汪汪叫完毕");
            Thread.Sleep(TimeSpan.FromSeconds(0.5));
    
            for (int i = 0; i < 6; i++)
            {
                Console.ForegroundColor = ConsoleColor.Magenta;
                Console.WriteLine("Main方法中的操作{0}",i);
                Thread.Sleep(TimeSpan.FromSeconds(0.5));
            }
            Console.ReadKey();
        }
    
        static void PrintRed() 
        {
            for (int i = 0; i < 5; i++)
            {
                Console.ForegroundColor = ConsoleColor.Red;
                Console.WriteLine(i);
                Thread.Sleep(TimeSpan.FromSeconds(1));
            }
        }
    }
    class Dog
    {
        public string DogName { get; set; }
        public ConsoleColor ConsoleColor { get; set; }
    
        public void WangWang() 
        {
            for (int i = 1; i < 4; i++)
            {
                Console.ForegroundColor = this.ConsoleColor;
                Console.WriteLine($"狗狗--{DogName},叫了第{i}声");
                Thread.Sleep(TimeSpan.FromSeconds(0.5));
            }
        }
    }
    

    使用方法名进行直接同步调用

    使用委托,间接同步调用

    //只改动Main方法中的部分代码,其余代码与上面的例子中代码保持一致
    static void Main(string[] args)
    {
        //将WangWang方法交给委托,然后进行间接同步调用
        Dog dog1 = new Dog() { DogName = "嘟嘟", ConsoleColor = ConsoleColor.Red };
        Dog dog2 = new Dog() { DogName = "壮壮", ConsoleColor = ConsoleColor.Green };
        Dog dog3 = new Dog() { DogName = "小强", ConsoleColor = ConsoleColor.Yellow };
    
        Action action1 = new Action(dog1.WangWang);
        Action action2 = new Action(dog2.WangWang);
        Action action3 = new Action(dog3.WangWang);
        action1.Invoke();
        Console.WriteLine($"{dog1.DogName}叫完了");
        action2.Invoke();
        Console.WriteLine($"{dog2.DogName}叫完了");
        action3.Invoke();
        Console.WriteLine($"{dog3.DogName}叫完了");
    
        for (int i = 0; i < 6; i++)
        {
            Console.ForegroundColor = ConsoleColor.Magenta;
            Console.WriteLine("Main方法中的操作{0}",i);
            Thread.Sleep(TimeSpan.FromSeconds(0.5));
        }
        Console.ReadKey();
    }
    

    使用委托间接同步调用方法

    使用Thread/Task等,显示异步(多线程)调用

    static void Main(string[] args)
    {
        //将WangWang方法交给一个子线程 线程启动后 便可异步执行WangWang方法
        Dog dog1 = new Dog() { DogName = "嘟嘟", ConsoleColor = ConsoleColor.Red };
        Dog dog2 = new Dog() { DogName = "壮壮", ConsoleColor = ConsoleColor.Green };
        Dog dog3 = new Dog() { DogName = "小强", ConsoleColor = ConsoleColor.Yellow };
    
        Thread thread1 = new Thread(dog1.WangWang);
        Thread thread2 = new Thread(dog2.WangWang);
        Thread thread3 = new Thread(dog3.WangWang);
        thread1.Start();
        thread2.Start();
        thread3.Start();
    
        for (int i = 0; i < 6; i++)
        {
            Console.ForegroundColor = ConsoleColor.Magenta;
            Console.WriteLine("Main方法中的操作{0}",i);
            Thread.Sleep(TimeSpan.FromSeconds(0.5));
        }
        Console.ReadKey();
    }
    

    使用Thread类显示地异步调用方法

    使用委托,隐式异步(多线程)调用--BeginInvoke

    static void Main(string[] args)
    {
        //将WangWang方法交给委托,通过委托的BeginInvoke方法,可以隐式地实现异步调用
        Dog dog1 = new Dog() { DogName = "嘟嘟", ConsoleColor = ConsoleColor.Red };
        Dog dog2 = new Dog() { DogName = "壮壮", ConsoleColor = ConsoleColor.Green };
        Dog dog3 = new Dog() { DogName = "小强", ConsoleColor = ConsoleColor.Yellow };
    
        Action action1 = new Action(dog1.WangWang);
        Action action2 = new Action(dog2.WangWang);
        Action action3 = new Action(dog3.WangWang);
        action1.BeginInvoke(null,null);
        action2.BeginInvoke(item => { Console.WriteLine($"{(item.AsyncState as Dog).DogName}叫完了"); },dog2);
        action3.BeginInvoke(xx => { Console.WriteLine($"{dog3.DogName}叫完了"); },null);
    
        for (int i = 0; i < 6; i++)
        {
            Console.ForegroundColor = ConsoleColor.Magenta;
            Console.WriteLine("Main方法中的操作{0}",i);
            Thread.Sleep(TimeSpan.FromSeconds(0.5));
        }
        Console.ReadKey();
    }
    

    使用委托的BeginInvoke方法隐式异步调用

    • 可以看出:BeginInvoke方法隐式地将方法放到多线程中去执行,BeginInvoke方法调用后立刻返回,接着执行Main方法中的下一行代码。BeginInvoke方法还接受两个参数:第一个是委托类型的回调--当多线程的方法执行结束后执行回调方法;第二个参数--异步调用的方法结束后,该参数会作为调用结果IAsyncResult实例的AsyncState属性值
    • 还可以看出:使用Thread启动多线程后,并不能得知什么时候异步调用的方法执行完毕;我们就不能在异步方法执行完毕后,进行一些相应的后续操作。但是,BeginInvoke就可以

    以上便是对使用委托进行方法的异步调用的总结,记录下来以便以后查阅。

  • 相关阅读:
    js常用代码整理
    java 序列化时排除指定属性
    FastJson bean序列化属性顺序问题
    用logger在控制台打印信息
    UNITY 内存问题资料收集
    数组指针和指针数组的区别
    inl文件介绍
    C++防止文件重复包含
    VS2017 Intelligense C++ 设置的几个重点
    GPU架构图
  • 原文地址:https://www.cnblogs.com/bigbosscyb/p/13789824.html
Copyright © 2011-2022 走看看