根据代码示例来学习,

  1. 创建一个函数来模拟时间消耗的方法,此处为GetSomeThing函数。

  2. 要使用异步编程,需要使用一个async修饰的方法来包装调用GetSomeThing函数,此函数的返回值为Task类型,该类型表示进行并行运算的任务引用。此处示例为ConsumeManyTime函数。

  3. 现在就可以直接使用异步方式了,参考TestOne()函数中的代码,其实就是直接调用第二步中的函数ConsumeManyTime();

总结:
异步编程虽然示例三步,但是实际上就是两步的事情,第一步是模拟应用,跟异步编程本身没有关系,第二步包装一个Task返回类型的async修饰的方法,该方法实际调用应用函数,第三步调用第二步的方法,从而执行对模拟应用的异步执行。

附加:
除了异步编程以外,C#还提供了并发编程相关功能,极大简化了并发任务的开发,可以让开发人员无需创建线程池以及管理线程这些工作,就可以直接使用并发开发带来的优势。 示例代码见Testpallral()

代码如下

class Program
    {

        static int i = 0;
        //模拟耗时的运算或者IO
        public static bool GetSomeThing(string a)
        {
            Thread.Sleep((new Random()).Next()%10*1000);
            i++;
            Console.WriteLine(DateTime.Now.ToLongTimeString()+"5-" + Thread.GetCurrentProcessorId().ToString());
            return true;
        }
        //生成一个task类型,其中包装调用GetSomeThing
        public static Task GetSomeThingAsync(string a)
        {
            return Task.Run(()=> { return GetSomeThing(a); }
            );
        }
    //方式1:包装给调用方使用的方法,使用async修饰,因为里面有await。 调用方执行到await会立即返回,后续的内容不再直接调用, await之后的方法都会在可能在其他线程中使用,
    public async static void ConsumeManyTime()
    {
        Console.WriteLine(DateTime.Now.ToLongTimeString() + "3-" +Thread.GetCurrentProcessorId().ToString());
        bool result = await GetSomeThingAsync("test");
        Console.WriteLine(DateTime.Now.ToLongTimeString() + "4-" +Thread.GetCurrentProcessorId().ToString());
    }
    //方式2:这种调用方式是在异步执行完毕后,可以继续执行预定的后续函数,可以理解为一种回调机制。
    public static void ContinueTaskWithConsumeManyTime()
    {
        Task t1 = GetSomeThingAsync("test");
        t1.ContinueWith(t => { Console.WriteLine("after await finished " + t.Result + " " + Thread.GetCurrentProcessorId().ToString() + " " + i.ToString()); });
    }
    //方式3:多任务等待方式
    public static async void TaskWhenConsumeManyTime()
    {
        Task t1 = GetSomeThingAsync("test");
        Task t2 = GetSomeThingAsync("test");
        await Task.WhenAll(t1, t2);
        Console.WriteLine(DateTime.Now.ToLongTimeString() + "6-" + Thread.GetCurrentProcessorId().ToString());

    }

    //async 和await的基本使用
    public static void TestOne()
    {
        Console.WriteLine(DateTime.Now.ToLongTimeString() + "1-" + Thread.GetCurrentProcessorId().ToString());
        ConsumeManyTime();
        ConsumeManyTime();
        Console.WriteLine(DateTime.Now.ToLongTimeString() + "2-" + Thread.GetCurrentProcessorId().ToString());
        Console.WriteLine("继续输入");
        while (Console.ReadLine() != "stop")
        {
            Console.WriteLine("继续输入");
        }
    }

    public static void TestWithContinue()
    {
        Console.WriteLine(DateTime.Now.ToLongTimeString() + "1-" + Thread.GetCurrentProcessorId().ToString());
        ContinueTaskWithConsumeManyTime();
        ContinueTaskWithConsumeManyTime();
        Console.WriteLine(DateTime.Now.ToLongTimeString() + "2-" + Thread.GetCurrentProcessorId().ToString());
        Console.WriteLine("继续输入");
        while (Console.ReadLine() != "stop")
        {
            Console.WriteLine("继续输入");
        }
    }

    public static void TestWhen()
    {
        Console.WriteLine(DateTime.Now.ToLongTimeString() + "1-" + Thread.GetCurrentProcessorId().ToString());
        TaskWhenConsumeManyTime();

        Console.WriteLine(DateTime.Now.ToLongTimeString() + "2-" + Thread.GetCurrentProcessorId().ToString());
        Console.WriteLine("继续输入");
        while (Console.ReadLine() != "stop")
        {
            Console.WriteLine("继续输入");
        }
    }

    public static  void Testpallral()
    {
        ParallelLoopResult result =

              Parallel.For(0, 100, async (int i) =>

              {

                  Console.WriteLine(DateTime.Now.ToLongTimeString() + "{0}, task: {1}, thread: {2}", i,

                  Task.CurrentId, Thread.CurrentThread.ManagedThreadId);

                  await Task.Delay(10);
                  Console.WriteLine(DateTime.Now.ToLongTimeString() + "after delay");

              });

        while (Console.ReadLine() != "stop")
        {
            Console.WriteLine("继续输入");
        }
    }

    public static void Testpallral2()
    {
        ParallelLoopResult result =
              Parallel.For(0, 100,async(int i, ParallelLoopState pls) =>
              {
                  Console.WriteLine(DateTime.Now.ToLongTimeString() + "{0}, task: {1}, thread: {2}", i,
                  Task.CurrentId, Thread.CurrentThread.ManagedThreadId);

                  await Task.Delay(10);
                    if (i > 5) pls.Break();
            Console.WriteLine(DateTime.Now.ToLongTimeString() + "after delay");

              }
        );

        while (Console.ReadLine() != "stop")
        {
            Console.WriteLine("继续输入");
        }
    }
    static void Main(string[] args)
    {
        //TestWhen();
        //Testpallral2();

    }

}