zoukankan      html  css  js  c++  java
  • 多线程 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}");
                });

    结果:

  • 相关阅读:
    零碎知识点
    安卓内存泄漏8种可能
    检测内存泄漏
    kotlin协程
    webview
    安卓各布局优缺点
    splice方法
    angular服务使用
    CSS3的一些笔记
    let、var、const
  • 原文地址:https://www.cnblogs.com/19930521zhang/p/15787230.html
Copyright © 2011-2022 走看看