Task的用法

Task用法记录总结

1.创建Task的3种方法

1.1new方式实例化一个Task,需要通过Start方法启动

             Task task = new Task(() =>
            {
                Thread.Sleep(100);
                Console.WriteLine($"hello, task1的线程ID为{Thread.CurrentThread.ManagedThreadId}");
            });
            task.Start();

task.Start方式,每个task都在不同的线程中

 代码:

private static void Main(string[] args)
    {
        Console.WriteLine("Hello, World!");

        Task task1 = new Task(() =>
        {
            Console.WriteLine("task1 is running on a thread id {0}. Is thread pool thread: {1}",
             Thread.CurrentThread.ManagedThreadId,
             Thread.CurrentThread.IsThreadPoolThread);
        });

        Task task2 = new Task(() =>
        {
            Console.WriteLine("task2 is running on a thread id {0}. Is thread pool thread: {1}",
             Thread.CurrentThread.ManagedThreadId,
             Thread.CurrentThread.IsThreadPoolThread);
        });

        Task task3 = new Task(() =>
        {
            Console.WriteLine("task3 is running on a thread id {0}. Is thread pool thread: {1}",
             Thread.CurrentThread.ManagedThreadId,
             Thread.CurrentThread.IsThreadPoolThread);
        });
        //不在同一个线程
        task1.Start();
        task2.Start();
        task3.Start();

        //在同一个线程
        //task1.RunSynchronously();
        //task2.RunSynchronously();
        //task3.RunSynchronously();

        Task.WaitAll(task1,task2,task3);



    }
View Code

task.RunSynchronously方式,每个任务都在同一个线程。task会阻塞主线程

task.Start方式,不会阻塞主线程

1.2Task.Factory.StartNew(Action action)创建和启动一个Task

Task task2 = Task.Factory.StartNew(() =>
            {
                Thread.Sleep(100);
                Console.WriteLine($"hello, task2的线程ID为{Thread.CurrentThread.ManagedThreadId}");
            });

创建后自动运行Task

1.3Task.Run(Action action)将任务放在线程池队列,返回并启动一个Task

 Task task3 = Task.Run(() =>
            {
                Thread.Sleep(100);
                Console.WriteLine($"hello, task3的线程ID为{Thread.CurrentThread.ManagedThreadId}");
            });

创建后自动运行Task

2.Task的Wait/WaitAny/WaitAll方法

task.Wait() 表示等待task执行完毕 

Task.WaitAll(Task[] tasks) 表示只有所有的task都执行完成了再解除阻塞

 

private static void Main(string[] args)
    {
        Console.WriteLine("start");
        Task task1 = new Task(() =>
        {
            Thread.Sleep(1000);
             Console.WriteLine("task1 is running on a thread id {0}. Is thread pool thread: {1}",
             Thread.CurrentThread.ManagedThreadId,
             Thread.CurrentThread.IsThreadPoolThread);
        });
        Task task2 = new Task(() =>
        {
            Thread.Sleep(2000);
            Console.WriteLine("task2 is running on a thread id {0}. Is thread pool thread: {1}",
             Thread.CurrentThread.ManagedThreadId,
             Thread.CurrentThread.IsThreadPoolThread);
        });
        Task task3 = new Task(() =>
        {
            Thread.Sleep(3000);
            Console.WriteLine("task3 is running on a thread id {0}. Is thread pool thread: {1}",
             Thread.CurrentThread.ManagedThreadId,
             Thread.CurrentThread.IsThreadPoolThread);
        });
       // 不在同一个线程
        task1.Start();
        task2.Start();
        task3.Start();

        Task.WaitAll(task1,task2,task3);
        Console.WriteLine("task 1 2 3 end");
    }

 

task1 等待1秒,task2等待2秒 task3等待3秒,使用WaitAll,则会等所有任务执行完毕之后才结束。

 

Task.WaitAny(Task[] tasks) 表示只要有一个task执行完毕就解除阻塞

 task1 等待1秒,task2等待2秒 ,task3等待3秒,使用WaitAny,只要有一个task结束,就结束阻塞。这里task最先结束

3.Task的延续操作(WhenAny/WhenAll/ContinueWith)

Task.WhenAll(task1, task2, task3).ContinueWith((t) => {
            //dosomething
            Console.WriteLine("task 1 2 3 all End");
        
        });

当task完成后执行某些操作。

4.带返回值的Task

 private static int Main(string[] args)
    {
        //1.new方式实例化一个Task
        Task<int> task = new Task<int>(() =>
        {
            Thread.Sleep(100);
            Console.WriteLine($"hello, task1的线程ID为{Thread.CurrentThread.ManagedThreadId}");
            return 12;
        });
        task.Start();
        int ret = task.Result;
        task.Wait();
        Console.WriteLine(ret);

        //2.Task.Run
        Task<int> task2 = (Task<int>)Task.Run(() =>
        {
            Thread.Sleep(1000);
            Console.WriteLine($"hello, task2的线程ID为{Thread.CurrentThread.ManagedThreadId}");
            return 13;
        });
        int ret2 = task2.Result;
        Console.WriteLine(ret2);

        //3.Task.Factory.StartNew
        Task<int> task3 = Task.Factory.StartNew(() =>
        {
            Thread.Sleep(100);
            Console.WriteLine($"hello, task3的线程ID为{Thread.CurrentThread.ManagedThreadId}");
            return 14;
        });
        int ret3 = task3.Result;
        Console.WriteLine(ret3);

        return 0;
    }

5.异步async awit

 private static void Main(string[] args)
    {
        Console.WriteLine("begin download");
        Task task =  download();

        Console.WriteLine("end download");
    }

   static async Task<int> download()
    {
        Console.WriteLine("开始");
        await Task.Run(() => { Thread.Sleep(2222); });
        Console.WriteLine("结束");
        return 666;
    }

 

可以看到主线程退出了,但download异步方法还没结束。

 

深入理解异步:

一文说通C#中的异步编程 - 老王Plus - 博客园 (cnblogs.com)

posted @ 2022-08-24 16:23  薛定谔的小灯泡  阅读(716)  评论(0编辑  收藏  举报