首页 > 作文

c#中task与thread区别及其使用的方法示例

更新时间:2023-04-05 00:28:08 阅读: 评论:0

目录
1.什么是thread2.什么是task3.创建一个task任务有两种模式:

1.什么是thread

当我们提及多线程的时候会想到thread和threadpool,这都是异步操作,threadpool其实就是thread的集合,具有很多优势,不过在任务多的时候全局队列会存在竞争而消耗资源。thread默认为前台线程,主程序必须等线程跑完才会关闭,而threadpool相反。

总结:threadpool确实比thread性能优,但是两者都没有很好的api区控制,如果线程执行无响应就只能等待结束,从而诞生了task任务。

2.什么是task

task简单地看就是任务,那和thread有什么区别呢?task的背后的实现也是使用了线程池线程,但它的性能优于threadpoll,因为它使用的不是线程池的全局队列,而是使用的本地队列,使线程之间的资源竞争减少。同时task提供了丰富的api来管理线程、控制。但是相对前面的两种耗内存,task依赖于cpu对于多核的cpu性能远超前两者,单核的cpu三者的性能没什么差别。

3.创建一个task任务有两种模式:

1.使用factory创建会直接执行,使用new创建不会执行,必须等到start启动之后才执行。

​ public void test()        {            var testtask = new task(() =>            {                console.writeline("task start");            });            testtask.start();            var factoryteak = task.factory.startnew(() =>            {                console.writeline("factory task start");            });        } ​

2.我们来看看task的生命周期

​var testtask = new task(() =>            {                console.writeline("task start");                system.threading.thread.sleep(2000);            });            console.writeline(testtask.status);            testtask.start();            console.writeline(testtask.status);            console.writeline(testtask.status);                     testtask.wait();            console.writeline(testtask.status);            console.writeline(testtask.status); ​

输出结果:

created
task start
running
running
rantocompletion
rantocompletion

可以看出task确实是异步执行,并且wait很好地控制了task。

3.下面演示几个控制task的方法

     var testtask = new task(() =>            {                console.writeline("task start");                system.threading.thread.sleep(2000);            });            testtask.start();            testtask.wait();
 var testtask = new task(() =>            {               console.writeline("task start");               system.threading.thread.sleep(2000);            });            testtask.start();var factoryteak = task.factory.startnew(() =>               {                                   console.writeline("factory task start");               });              task.waitall(testtask, factoryteak);              console.writeline("end"); ​
 var testtask = new task(() =>            {                console.writeline("task start");                system.threading.thread.sleep(2000);            });            testtask.start(); var factoryteak = task.factory.startnew(() =>               坚不可摧什么意思{                                    console.writeline("factory task start");                });                task.waitany(testtask, factoryteak);                console.writeline("end");

通过wait()对单个task进行等待,task.waitall()对多个task进行等待,waitany()执行任意一个task就往下继续执行。

4.task的回调执行

  var testtask = new task(() =>            {                console.writeline("task start");                system.threading.thread.sleep(2000);            });            testtask.start();            var resulttest = testtask.continuewith<string>((task) => {                console.writeline("testtask end");                return "end";            });            console.writeline(resulttest.result);

5.task的取消

首先创建一个取消task的令牌的实例,在不启动task直接取消:

var tokensource = new cancellationtokensource();//创建取消task实例            var testtask = new task(() =>            {                for (int i = 0; i < 6; i++) {                    system.threading.thread.sleep(1000);                }                           },tokensource.token);            console.writeline(testtask.status);            tokensource.token.register(()=> {                console.writeline("task is to cancel");            });            tokensource.cancel();            console.writeline(testtask.status);

输出结果:

created
task is to cancel
canceled

如果task启动了真的取消了task?

  var tokensource = new cancellationtokensource();//创建取消task实例            var testtask = new task(() =>            {                for (int i = 0; i <6; i++) {                    system.threading.thread.sleep(1000);                }                           },tokensource.token);            console.writeline(testtask.status);            testtask.start();            console.writeline(testtask.status);            tokensource.token.register(()=> {                console.writelin有关雪的诗句e("task is to cancel");            });            tokensource.cancel();            console.writeline(testtask.status);            for (int i = 0; i < 10; i++)            {                system.threading.thread.sleep(1000);                console.writeline(testtask.status);            }

输出结果:

created
waitingtorun
task is to cancel
running
running
running
running
running
running
rantocompletion
rantocompletion
rantocompletion
rantocompletion
rantocompletion

可以看出其实并没有取消task,此时task还在继续跑。

6.task的嵌套

  var parenttask = new task(()=> {                var childtask = new task(() =>{                    system.threading.thread.sleep(2000);                    consol登高原文及翻译e.writeline("childtask to start");                });                childtask.start();                console.writeline("parenttask to start");            });            parenttask.start();            parenttask.wait();            console.writeline("end");

此时为普通关联,父task和子task没影响

  var parenttask = new task(()=> {                var childtask = new task(() =>{                    system.threading.thread.sleep(2000);                    console.writeline("childtask to start");                }, taskcreationoptions.attachedtoparent);                childtask.start();                console.writeline无锡灵山大佛("parenttask to start");            } );            parenttask.start();            parenttask.wait();            console.writeline("end");

此时为父task和子task关联,wait会一直等待父子task执行完。

6.task死锁的问题

我们可以设置最大等待时间,如果超过了等待时间,就不再等待,下面我们来修改代码,设置最大等待时间为5秒(项目中可以根据实际情况设置),如果超过5秒就输出哪个任务出错了

7.对spinlock的使用

举例来说parallel.for和parallel.foreach是线程不安全的,有可能达不到你的预期,此时就需要加锁来解决此问题,我们可以加lock和spinlock(自旋锁)来解决

            spinlock slock = new spinlock(fal);            var testlock= new object();            long sum1 = 0;            long sum2 = 0;            long sum3 = 0;            parallel.for(0, 100000, i =>            {                sum1 += i;            });             parallel.for(0, 100000, i =>            {                bool locktaken = fal;                try                {                    slock.enter(ref locktaken);                    sum2 += i;                }                finally                {                    if (locktaken)                        slock.exit(fal);                }            });            parallel.for(0, 100000, i =>            {                lock(testlock)                {                    sum3 += i;  浙江大专排名              };            });            console.writeline("num1的值为:{0}", sum1);            console.writeline("num2的值为:{0}", sum2);            console.writeline("num3的值为:{0}", sum3);

输出结果:

num1的值为:1660913202
num2的值为:4999950000
num3的值为:4999950000

num1的值为:2754493646
num2的值为:4999950000
num3的值为:4999950000

num1的值为:4999950000
num2的值为:4999950000
num3的值为:4999950000

最后看看threadpoll和task的结构图:

threadpool:

task:

本文发布于:2023-04-05 00:28:07,感谢您对本站的认可!

本文链接:https://www.wtabcd.cn/fanwen/zuowen/83d0e7a9907094b00f8efa53e1c80287.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

本文word下载地址:c#中task与thread区别及其使用的方法示例.doc

本文 PDF 下载地址:c#中task与thread区别及其使用的方法示例.pdf

标签:值为   线程   队列   性能
相关文章
留言与评论(共有 0 条评论)
   
验证码:
Copyright ©2019-2022 Comsenz Inc.Powered by © 专利检索| 网站地图