c#异步学习笔记 Task类,async/await

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/ITzhongzi/article/details/80652991

Task理解:字面意思是 “任务”,用来执行异步操作。

Task的用法1:

  •     初始化: Task tack = new Task(委托方法);  //委托方法也可以是lambda表达式或者匿名函数
  •     异步执行委托的方法: task.start();    

Task的用法2:

  • 直接调用Task封装的静态方法Run: Task.Run(委托方法);//这样在定义玩之后会开一个新线程直接执行委托的方法

    注意:系统要执行Task的委托函数时,会开一个新的线程去执行,主线程继续执行下面的代码

async/await用法:

  •     主线程碰到await后会立刻返回,以非阻塞的形式执行后面的代码。
  •     在Task对象前面用 await会阻塞线程,直到Task中的异步操作结束,并返回结果。程序才会继续执行。


示例demo:(展示task初始化,基本使用)

using System;
using System.Threading;
using System.Threading.Tasks;

namespace ConsoleApplication1
{
    internal class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("我是主线程,线程ID:" + Thread.CurrentThread.ManagedThreadId);
            //task用法一  
            Task task1 = new Task(() => MyAction());
            task1.Start();

            //task用法二  
            var strRes = Task.Run<string>(() => { return GetReturnStr(); });
            Console.WriteLine(strRes.Result);

            //task->async异步方法和await,主线程碰到await时会立即返回,继续以非阻塞形式执行主线程下面的逻辑  
            Console.WriteLine("---------------------------------");
            Console.WriteLine("①我是主线程,线程ID:{0}", Thread.CurrentThread.ManagedThreadId);
            var testResult = TestAsync();
            Console.ReadKey();
        }

        static async Task TestAsync()
        {
            Console.WriteLine("②调用GetReturnResult()之前,线程ID:{0}。当前时间:{1}", Thread.CurrentThread.ManagedThreadId,
                DateTime.Now.ToString("yyyy-MM-dd hh:MM:ss"));
            var name = GetReturnResult();
            Console.WriteLine("④调用GetReturnResult()之后,线程ID:{0}。当前时间:{1}", Thread.CurrentThread.ManagedThreadId,
                DateTime.Now.ToString("yyyy-MM-dd hh:MM:ss"));
            Console.WriteLine("⑥得到GetReturnResult()方法的结果一:{0}。当前时间:{1}",await name,
                DateTime.Now.ToString("yyyy-MM-dd hh:MM:ss"));
            Console.WriteLine("⑥得到GetReturnResult()方法的结果二:{0}。当前时间:{1}", name.GetAwaiter().GetResult(),
                DateTime.Now.ToString("yyyy-MM-dd hh:MM:ss"));
        }

        static async Task<string> GetReturnResult()
        {
            Console.WriteLine("③执行Task.Run之前, 线程ID:{0}", Thread.CurrentThread.ManagedThreadId);
            return await Task.Run(() =>
            {
                Thread.Sleep(2000);
                Console.WriteLine("⑤GetReturnResult()方法里面线程ID: {0}", Thread.CurrentThread.ManagedThreadId);
                return "我是返回值";
            });
        }

        static void MyAction()
        {
            Console.WriteLine("我是新进程,线程ID:() MyAction " + Thread.CurrentThread.ManagedThreadId);
        }

        static string GetReturnStr()
        {
            return "我是返回值 ,GetReturnStr 线程ID:" + Thread.CurrentThread.ManagedThreadId;
        }
    }
}

运行结果:

    

案例精讲:

using System;
using System.Threading;
using System.Threading.Tasks;

namespace ConsoleApplication1
{
    internal class Program
    {
        static void Main(string[] args)
        {
            for (int i = 0; i < 4; i++)
            {
                TestAsync();
            }

            Console.ReadLine();
        }

        static async Task TestAsync()
        {
            Console.WriteLine("Test()开始, Thread Id: {0}\r\n", Thread.CurrentThread.ManagedThreadId);
            var name = GetNameAsync(); //我们这里没有用 await,所以下面的代码可以继续执行
            // 但是如果上面是 await GetNameAsync(),下面的代码就不会立即执行,输出结果就不一样了。            
            var res = await name;
            //
            Console.WriteLine("await GetName1: {0},得到结果进行其它操作", res);
            Console.WriteLine("Test()结束.\r\n");
        }

        static async Task<string> GetNameAsync()
        {
            // 这里还是主线程
            Console.WriteLine("GetName()开始, thread Id is: {0}", Thread.CurrentThread.ManagedThreadId);
            return await Task.Run(() =>
            {
                Thread.Sleep(1000);
                Console.WriteLine("'GetName' Thread Id: {0}", Thread.CurrentThread.ManagedThreadId);
                return "Jesse";
            });
            Console.ReadLine();
        }
    }
}

输出结果:


代码运行逻辑解析:

  1.     主线程执行到 for循循环处,调用四个 异步方法 TestAsync();
  2.     主线程进入TestAsync内部继续执行,遇到异步方法 GetNameAsync();
  3.     主线程进入GetNameAsync内部继续执行,遇到 await/return 返回,并将 Task任务存储在变量 name 中
  4.     主线程回到 TestAsync 继续执行 遇到 await name ,开启一个线程,执行Task变量name内部的委托方法,并且,主线程立刻返回,执行下一次循环的 TestAsync 。
  5.     四次循环的执行逻辑综上所述,因为委托方法内部 让程序 休眠 一秒,也就是 执行委托方法的 四个子线程 都会休眠一秒,但主线程 是一直在执行的。    

        

        即:

                Test()开始, Thread Id: 1

                GetName()开始, thread Id is: 1

        首先会连续输出四次,一秒 之后, 四个子线程再输出 委托方法中打印的内容。 


猜你喜欢

转载自blog.csdn.net/ITzhongzi/article/details/80652991