C# -多线程任务 Task

背景

公司的自动化测试平台是 C# 语言的,因此有幸学习下 c#。

C#多线程

搜索到的是这篇文章,是一个连载的,由浅入深。主要讲的是Task,里面也有demo,非常详细。

https://www.cnblogs.com/yunfeifei/p/4106318.html

Thread

Thread默认为前台线程,也可以设置为后台线程,主程序必须等待线程执行完毕后才可退出程序。开启一个新线程,线程不做任何操作,都要消耗1M左右的内存,所以是伪多线程,感觉就是在一个cpu上一个一个的执行,和之前的顺序有差别。
在这里插入图片描述

using System.Threading;
new Thread(() => 
{
    Thread.CurrentThread.IsBackground = true; 
    /* run your code here */ 
    Console.WriteLine("Hello, world"); 
}).Start();

更多资料参考官方的
https://docs.microsoft.com/en-us/dotnet/api/system.threading.thread?view=netframework-4.8

ThreadPoll是线程池 其目的是为了减少开启新线程消耗的资源(使用线程池中的空闲线程,不必在开启新线程,以及统一管理线程(线程池中的线程执行完毕后,回归到线程池里,等待新任务).

总结:ThreadPoll性能优于Thread,但是Thread和ThreadPoll对线程的控制都不是很好,例如线程等待(线程执行一段时间无响应后,直接停止线程,释放资源 等 都没有直接的API来控制 只能通过硬编码来实现,同时ThreadPool使用的是线程池全局队列,全局队列中的线程依旧会存在竞争共享资源的情况,从而影响性能。

Task

Task的背后的实现也是使用了线程池线程,但它的性能优于ThreadPoll,因为它使用的不是线程池的全局队列,而是使用的本地队列,使线程之间的资源竞争减少。同时Task提供了丰富的API来管理线程、控制。但是相对前面的两种耗内存,Task依赖于CPU对于多核的CPU性能远超前两者,单核的CPU三者的性能没什么差别。

官方资料文档 https://docs.microsoft.com/en-us/dotnet/api/system.threading.tasks.task?view=netframework-4.8

创建一个task也有3种方式来操作,Task.Factory.StartNew()Task run()new Task(), 前面2种是一样的,不需要用start来开始执行,后面一种需要start来执行的。

需要注意的是,start()后,并不是立即执行的。

Task t = Task.Factory.StartNew( () => {
                                  // Just loop.
                                  int ctr = 0;
                                  for (ctr = 0; ctr <= 1000000; ctr++)
                                  {}
                                  Console.WriteLine("Finished {0} loop iterations",
                                                    ctr);
                               } );

new 一个

var task1 = new Task(() =>
         {
            Console.WriteLine("Task 1 Begin");
            System.Threading.Thread.Sleep(2000);
            Console.WriteLine("Task 1 Finish");
         });
 task1.Start();

取消任务的话,需要一个CancellationTokenSourcetoken来取消即可。

var tokenSource = new CancellationTokenSource();
var token = tokenSource.Token;
var task = Task.Factory.StartNew(() =>
         {
            for (var i = 0; i < 1000; i++)
            {
               System.Threading.Thread.Sleep(1000);
               if (token.IsCancellationRequested)
               {
                  Console.WriteLine("Abort mission success!");
                  return;
               }
            }
         }, token);
tokenSource.Cancel();

特别需要注意的是,这个 task开始后,并不是立即执行的,因此后面需要这个task里面的值或者其他东西的话,需要检测其状态或者其他值。

posted @ 2019-09-04 10:20  叉叉敌  阅读(288)  评论(0编辑  收藏  举报