异步编程:利用委托实现的.NET历史上第一个异步编程模型

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

异步编程:利用委托实现的.NET历史上第一个异步编程模型

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

异步编程:利用委托实现的.NET历史上第一个异步编程模型

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

  • 程序运行起来就会创建一个进程;
  • 一个进程中可以有多个线程;
  • 同步调用是指在一个线程中,顺次执行;
  • 异步调用需要依靠多线程;
  • 同步、串行、单线程 指的是一个意思;
  • 异步、并行、多线程 指的是一个意思;
    异步编程:利用委托实现的.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));
        }
    }
}

异步编程:利用委托实现的.NET历史上第一个异步编程模型

使用委托,间接同步调用

//只改动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();
}

异步编程:利用委托实现的.NET历史上第一个异步编程模型

使用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();
}

异步编程:利用委托实现的.NET历史上第一个异步编程模型

使用委托,隐式异步(多线程)调用--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();
}

异步编程:利用委托实现的.NET历史上第一个异步编程模型

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

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