多线程 Task学习

线程启动的四种方式:

方式1:

Task task = new Task(() =>
            {
                Console.WriteLine($"启动线程方式一,当前线程id:{Thread.CurrentThread.ManagedThreadId.ToString("00")}");
            });
task.Start();

方式2:

Task.Run(() =>
            {
                Console.WriteLine($"启动线程方式二,当前线程id:{Thread.CurrentThread.ManagedThreadId.ToString("00")}");
            });

方式3:

TaskFactory taskFactory = new TaskFactory();
taskFactory.StartNew(() =>
            {
                Console.WriteLine($"启动线程方式三,当前线程id:{Thread.CurrentThread.ManagedThreadId.ToString("00")}");
            });

方式4:

TaskFactory taskFactoryTwo = Task.Factory;
taskFactoryTwo.StartNew(() =>
            {
                Console.WriteLine($"启动线程方式四,当前线程id:{Thread.CurrentThread.ManagedThreadId.ToString("00")}");
            });

整体代码:

static void Main(string[] args)
        {
            Console.WriteLine($"*** Start,当前线程id:{Thread.CurrentThread.ManagedThreadId.ToString("00")},时间:{DateTime.Now}***");
            Task task = new Task(() =>
            {
                Console.WriteLine($"启动线程方式一,当前线程id:{Thread.CurrentThread.ManagedThreadId.ToString("00")}");
            });
            task.Start();

            Task.Run(() =>
            {
                Console.WriteLine($"启动线程方式二,当前线程id:{Thread.CurrentThread.ManagedThreadId.ToString("00")}");
            });

            TaskFactory taskFactory = new TaskFactory();
            taskFactory.StartNew(() =>
            {
                Console.WriteLine($"启动线程方式三,当前线程id:{Thread.CurrentThread.ManagedThreadId.ToString("00")}");
            });

            TaskFactory taskFactoryTwo = Task.Factory;
            taskFactoryTwo.StartNew(() =>
            {
                Console.WriteLine($"启动线程方式四,当前线程id:{Thread.CurrentThread.ManagedThreadId.ToString("00")}");
            });
            Console.WriteLine($"*** End,当前线程id:{Thread.CurrentThread.ManagedThreadId.ToString("00")},时间:{DateTime.Now}***");
            Console.ReadKey();
        }
View Code

运行结果:

Thread.Sleep()和Task.Delay()的区别:

 Thread.Sleep()会等待线程(线程阻塞),Task.Delay()不会等待线程(非阻塞)

代码实现对比:

 Stopwatch stopwatch = new Stopwatch();
            stopwatch.Start();
            Thread.Sleep(3000);//等待3000ms,会等待线程
            stopwatch.Stop();
            Console.WriteLine($"Thread.Sleep(3000)执行 总耗时长:{stopwatch.ElapsedMilliseconds} ms");


Stopwatch stopwatch1 = new Stopwatch();
            stopwatch1.Start();
            Task.Delay(3000);//等待3000ms,不会等待线程,而是在等待多久以后,去执行些事件等
            stopwatch1.Stop();
            Console.WriteLine($"Task.Delay(3000)执行 总耗时长:{stopwatch1.ElapsedMilliseconds} ms");

结果:

 Task.Delay用途:一般是在等待多久之后,去执行些事件

示例代码:

 Stopwatch stopwatch2 = new Stopwatch();
            Console.WriteLine("开始计时");
            stopwatch2.Start();
            Task.Delay(3000).ContinueWith(s =>
            {//不阻塞主线程,
                Console.WriteLine("去执行事件");
                stopwatch2.Stop();
                Console.WriteLine("结束计时");
                Console.WriteLine($"Task.Delay(3000)执行 总耗时长:{stopwatch2.ElapsedMilliseconds} ms");
            });

结果:

线程任务控制:

开启3个线程任务,当任务全部完成后,执行最后的提示:

代码

List<Task> taskList = new List<Task>();
            TaskFactory taskFactory = Task.Factory;
            Console.WriteLine($"开始执行所有线程,当前时间为:{DateTime.Now}");
            taskList.Add(taskFactory.StartNew(() => 
            { Thread.Sleep(new Random().Next(3000, 5000));
                Console.WriteLine($"当前线程:{Thread.CurrentThread.ManagedThreadId.ToString("00")}");
            }));
            taskList.Add(taskFactory.StartNew(() =>
            {
                Thread.Sleep(new Random().Next(3000, 5000));
                Console.WriteLine($"当前线程:{Thread.CurrentThread.ManagedThreadId.ToString("00")}");
            }));
            taskList.Add(taskFactory.StartNew(() =>
            {
                Thread.Sleep(new Random().Next(3000, 5000));
                Console.WriteLine($"当前线程:{Thread.CurrentThread.ManagedThreadId.ToString("00")}");
            }));
            Task.WaitAll(taskList.ToArray());
            Console.WriteLine($"所有线程都执行完成,当前时间为:{DateTime.Now}");

执行结果:

 开启三个线程,当第一个线程执行完成,就进行提示(不影响后面线程执行):

代码:

 List<Task> taskList = new List<Task>();
            TaskFactory taskFactory = Task.Factory;
            Console.WriteLine($"开始执行所有线程,当前时间为:{DateTime.Now}");
            taskList.Add(taskFactory.StartNew(() => 
            {
                Thread.Sleep(new Random().Next(3000, 8000));
                Console.WriteLine($"当前线程:{Thread.CurrentThread.ManagedThreadId.ToString("00")},当前时间为:{DateTime.Now}");
            }));
            taskList.Add(taskFactory.StartNew(() =>
            {
                Thread.Sleep(new Random().Next(3000, 8000));
                Console.WriteLine($"当前线程:{Thread.CurrentThread.ManagedThreadId.ToString("00")},当前时间为:{DateTime.Now}");
            }));
            taskList.Add(taskFactory.StartNew(() =>
            {
                Thread.Sleep(new Random().Next(3000, 8000));
                Console.WriteLine($"当前线程:{Thread.CurrentThread.ManagedThreadId.ToString("00")},当前时间为:{DateTime.Now}");
            }));
            //Task.WaitAll(taskList.ToArray());
            //Console.WriteLine($"所有线程都执行完成,当前时间为:{DateTime.Now}");
            taskFactory.ContinueWhenAny(taskList.ToArray(), ts =>
            {
                Console.WriteLine($"第一个线程执行完成,当前时间为:{DateTime.Now}");
            });

结果:

 开启三个线程,当第一个线程执行完成,就进行提示,并将线程参数传入到提示内容中(不影响后面线程执行):

代码:

List<Task> taskList = new List<Task>();
            TaskFactory taskFactory = Task.Factory;
            Console.WriteLine($"开始执行所有线程,当前时间为:{DateTime.Now}");
            taskList.Add(taskFactory.StartNew(obj =>
            {
                Thread.Sleep(new Random().Next(1000, 8000));
                Console.WriteLine($"当前线程:{Thread.CurrentThread.ManagedThreadId.ToString("00")},当前时间为:{DateTime.Now}");
            },$"传入参数为03"));
            taskList.Add(taskFactory.StartNew(obj =>
            {
                Thread.Sleep(new Random().Next(2000, 8000));
                Console.WriteLine($"当前线程:{Thread.CurrentThread.ManagedThreadId.ToString("00")},当前时间为:{DateTime.Now}");
            }, $"传入参数为03"));
            taskList.Add(taskFactory.StartNew(obj =>
            {
                Thread.Sleep(new Random().Next(3000, 8000));
                Console.WriteLine($"当前线程:{Thread.CurrentThread.ManagedThreadId.ToString("00")},当前时间为:{DateTime.Now}");
            }, $"传入参数为03"));
            //Task.WaitAll(taskList.ToArray());
            //Console.WriteLine($"所有线程都执行完成,当前时间为:{DateTime.Now}");
            taskFactory.ContinueWhenAny(taskList.ToArray(), ts =>
            {
                Console.WriteLine($"当前传入参数:{ts.AsyncState},第一个线程执行完成,当前时间为:{DateTime.Now}");
            });

结果:

原文地址:https://www.cnblogs.com/19930521zhang/p/15787230.html