当前位置:首页 > 软件开放 > 正文内容

dede调用代码(def调用)

软件开放8个月前 (03-13)295

前言

多线程无处不在,平常的开发过程中,应该算是最常用的基础技术之一了。以下通过Thread、ThreadPool、再到Task、Parallel、线程锁、线程取消等方面,一步步进行演示多线程的一些基础操作。欢迎大家围观。

如果大佬们有其他关于多线程的拓展,也欢迎在评论区进行留言,大佬们的知识互助,是.NET生态发展的重要一环,欢迎大佬们进行留言,帮助更多的人。

以下博客内容使用的一些环境:

系统环境:WIN 10

.NET 环境:.NET 6

VS 环境:VS 2022

其他:没了

正文

1、先创建一个.NET 6控制台项目,用来当做该博客文章的实验使用。

2、快速创建一个线程。ParameterizedThreadStart是一个委托,传入的参数是一个object类型。

展开全文

代码

ParameterizedThreadStart threadStart = new((obj) = {

Console.WriteLine($ "当前线程 的 ID = {Thread.CurrentThread.ManagedThreadId}");

});

Thread thread = new Thread(threadStart);

thread.Start;

Console.WriteLine($ "线程ID = {thread.ManagedThreadId}");

Console.ReadLine;

3、以上代码执行结果下图所示

4、新建一个类TestThread以及一个测试方法,用来做测试使用。

5、在program里面,把输出改成调用上面的方法再进行测试一下。

6、执行以后的输出结果,如下图所示

7、线程的等待(睡眠)。最简单的方式,是直接 Thread.Sleep(毫秒);

8、Thread的Join方法。代表线程执行完毕以后,才可以继续执行后续的代码。

如下图所示,在thread线程内部执行完成以后,很快就接着执行最后的打印输出方法了。

可以和以上的第7点进行比较输出结果。

9、Thread的Join方法,还可以传入参数,参数是毫秒值。

代表等下当前线程执行多长时间,如果超出设定的毫秒数,就不等了,直接执行后续的代码。

10、新增一个Test2方法,用来测试线程池ThreadPool使用。

11、WaitCallback也是一个委托。传入需要在线程池内执行的方法名称。

以下代码内,“线程池”字符串为执行的方法对应的参数。

代码

using MultiThread;

Console.WriteLine( "Hello, World!");

ThreadPool.QueueUserWorkItem(new WaitCallback(TestThread.Test2), "线程池");

Console.ReadLine;

12、除了直接传入回调方法,也可以直接在线程池开启的方法内,直接写代码块来当做多线程执行的部分。如下图所示,睡眠1000ms以及执行的方法,在线程池内运行。

一般用 .Set; 和 .WaitOne; 结对进行,如下图代码、注释部分以及执行结果。(可以对比输出时间)

14、使用Task快读创建一个线程。

如下图所示。最简单的方法:Task.Run(={ 代码块;});

15、也可以用以下方式,手动进行start启动,如图的代码所示。

16、也可以使用Task.Factory创建一个任务工厂来实现。

17、如果需要等待子线程执行完毕,才执行后续操作,可以使用Wait; 来实现。

18、如果只想等待子线程执行指定的时间,可以通过使用 Wait(毫秒数); 来实现。

这样等待,例如500ms以后,不管子线程是不是还在浪,都不会等待,直接继续执行后续代码。

19、 如果要在等待一段时间以后执行某些当做,可以使用Task.Delay(时间毫秒数).ContinuwWith( 要执行的代码块);

如下图所示的代码、注释以及运行输出结果。

20、如果有多个任务在执行期间,在任意一个线程执行完毕以后进行执行某种操作,可以使用 ContinueWhenAny来进行。

如下图所示的代码、注释和运行结果,以及图后附有源码。

代码

Console.WriteLine($ "{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss,fff ")} Hello, World!");

Task[] tasks = new Task[3];

TaskFactory factory = new;

tasks[0] = factory.StartNew(x = {

Thread.Sleep(1000);

Console.WriteLine($ "{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss,fff ")} tasks 0");

},null);

tasks[1] = factory.StartNew(x = {

Thread.Sleep(2000);

Console.WriteLine($ "{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss,fff ")} tasks 1");

}, null);

tasks[2] = factory.StartNew(x = {

Thread.Sleep(3000);

Console.WriteLine($ "{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss,fff ")} tasks 2");

}, null);

factory.ContinueWhenAny(tasks, x =

{

Console.WriteLine($ "{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss,fff ")} 我不晓得要打印啥子 ~ ~ ");

});

Console.ReadLine;

21、如果要等任务全部执行完毕以后才执行某个代码块,可以使用ContinueWhenAll。

22、使用TaskWaitAny 也可以实现任意任务执行完毕以后,执行后续动作。但是会占用主线程资源。

如图所示代码,大佬们应该可以看出来为什么了。

23、同样的,Task也可以在等待全部任务执行完毕以后进行执行后续动作。如下图演示。

24、Parallel允许线程并行执行。同时最大线程执行数量,类似于ThreadPool可以设置最大并发数量类似。其他不多说,看以下的代码和演示效果。

代码

using MultiThread;

Console.WriteLine($ "{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss,fff ")} Hello, World!");

ParallelOptions parallelOptions = new;

parallelOptions.MaxDegreeOfParallelism = 3;

Parallel.Invoke(parallelOptions,

=

{

Thread.Sleep(1000);

Console.WriteLine($ "{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss,fff ")} para1");

},

=

{

Thread.Sleep(2000);

Console.WriteLine($ "{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss,fff ")} para2");

},

=

{

Thread.Sleep(3000);

Console.WriteLine($ "{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss,fff ")} para3");

});

Console.WriteLine($ "{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss,fff ")} 我不晓得要打印啥子 ~ ~ ");

Console.ReadLine;

25、Parallel也可以遍历执行。

代码

using MultiThread;

Console.WriteLine($ "{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss,fff ")} Hello, World!");

ParallelOptions parallelOptions = new;

parallelOptions.MaxDegreeOfParallelism = 3;

Parallel.For(0, 10,parallelOptions, s =

{

Thread.Sleep(100);

Console.WriteLine($ "{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss,fff ")} para{s}");

});

Console.WriteLine($ "{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss,fff ")} 我不晓得要打印啥子 ~ ~ ");

Console.ReadLine;

26、新增一个方法,用来测试多线程锁使用。

27、在不加锁的情况下执行执行以下代码,方法体几乎同时被执行。但是实际上方法体如果只允许被同时一个线程访问的话,那么这样搞肯定是会乱子的,所以需要锁。

28、加了锁以后,查看到执行的结果,时间间隔基本上是1s左右,说明该方法体确实一次只被一个线程调用了。

29、另一种锁(原子锁),可以定义一个变量来进行原子交换。它的使用场景,一般是在轮询进行处理某些业务的时候,并且同时只允许一个线程进来,就可以使用这种锁。

和lock锁区别:lock锁是代码还没执行完,线程会一直等待,等执行完了就会继续进来。

如果线程一直被创建,lock外边会堆积越来越多的线程和资源,最严重的情况会导致系统内存不断飙升直到爆满;

原子锁的作用是,用于验证代码块是不是执行完了,还没执行完,就不鸟他了,线程也不会等待下去,而是直接跳过这部分的代码,继续执行后续的操作。如果后续没事情做了,那该干嘛干嘛了。

30、原子锁执行效果如下,一部分线程判断到代码被锁住,就跳过不管了,所以就不会有输出。

31、测试线程取消。先开启一些线程,以及有关的操作,如下图所示。

32、然后执行。结果比较尴尬,显示都是第100号线程,这是因为Task是多线程,在创建过程中,可能已经让i都执行到头了,所以再次获取到的i都是最后的值,即100.

33、在创建任务之前,引入一个中间变量,用来代替被遍历的i。然后执行结果和其他代码说明,如图所示。

34、看不到异常信息,那改成Task直接走一波,然后通过Task.WaitAll;进行捕捉异常信息。

如代码注释和演示截图所示。

代码

Console.WriteLine($ "{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss,fff ")} Hello, World!");

try

{

Task[] tasks = new Task[100];

CancellationTokenSource cancellation = new CancellationTokenSource;

for(int i = 0; i 100; i++)

{

string str = i.ToString;

tasks[i]= Task.Run( =

{

Thread.Sleep(100);

try

{

if(str == "10")

{

throw new Exception($ "{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss,fff ")} 第 -{str}- 号线程开始放弃治疗~~ 线程ID = {Thread.CurrentThread.ManagedThreadId}");

}

}

catch (Exception ex)

{

cancellation.Cancel; // 捕获异常,线程后续所有的线程都取消操作

Console.WriteLine(ex.Message);

}

cancellation.Token.ThrowIfCancellationRequested;

if(cancellation.IsCancellationRequested == false) // 默认为 false,代表正常

{

Console.WriteLine($ "{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss,fff ")} 第 -{str}- 号线程执行正常~~ 线程ID = {Thread.CurrentThread.ManagedThreadId}");

}

dede调用代码(def调用)

else

{

Console.WriteLine($ "{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss,fff ")} 第 -{str}- 号线程执行异常~~ 线程ID = {Thread.CurrentThread.ManagedThreadId}");

}

}, cancellation.Token);

}

Task.WaitAll(tasks);

Console.WriteLine($ "{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss,fff ")} 我不晓得要打印啥子 ~ ~ ");

}

catch (AggregateException ae)

{

foreach (var ex inae.InnerExceptions)

{

Console.WriteLine($ "{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss,fff ")} {ex.Message}");

}

}

Console.ReadLine;

35、以上就是这篇文章的全部内容。如果对你有帮助,欢迎点赞、转发、或留言。

转自:‍果糖大数据科技

转自:‍果糖大数据科技

版权声明:本文来源于网友收集或网友供稿,仅供学习交流之用,如果有侵权,请转告小编或者留言,本公众号立即删除。

支持小薇

关注公众号: DotNet开发跳槽 ❀

点分享

点收藏

点点赞

点在看

扫描二维码推送至手机访问。

版权声明:本文由飞速云SEO网络优化推广发布,如需转载请注明出处。

本文链接:http://muyuzhen.com/post/96204.html

分享给朋友:

“dede调用代码(def调用)” 的相关文章

高楼阳台怎么装修安全又好看(高层楼房的阳台怎么装修比较好)

高楼阳台怎么装修安全又好看(高层楼房的阳台怎么装修比较好)

今天给各位分享高楼阳台怎么装修安全又好看的知识,其中也会对高层楼房的阳台怎么装修比较好进行解释,如果能碰巧解决你现在面临的问题,别忘了关注本站,现在开始吧!本文目录一览: 1、高层住宅阳台怎么装修 2、高层顶楼露台应该如何装修 3、6米挑高阳台怎么装修好 4、买了高楼住宅,阳台怎么装?...

有没有做装修直播平台的(装修行业如何做直播)

有没有做装修直播平台的(装修行业如何做直播)

今天给各位分享有没有做装修直播平台的的知识,其中也会对装修行业如何做直播进行解释,如果能碰巧解决你现在面临的问题,别忘了关注本站,现在开始吧!本文目录一览: 1、未来装修行业直播能发展的像电商直播那样吗? 2、装修网站排行榜前十名有哪些?哪个网站最好? 3、关于装修的网站平台有哪些 4、...

网站登录页面html源码模板(html登录注册页面源码)

网站登录页面html源码模板(html登录注册页面源码)

本篇文章给大家谈谈网站登录页面html源码模板,以及html登录注册页面源码对应的知识点,希望对各位有所帮助,不要忘了收藏本站喔。 本文目录一览: 1、如何查看网站HTML源代码 2、HTML代码基础知识:如何查看一个网页的HTML源代码? 3、如何获取一个网页完整的HTML代码 4、如...

齐家装修网效果图(齐家装修效果图卫生间)

齐家装修网效果图(齐家装修效果图卫生间)

今天给各位分享齐家装修网效果图的知识,其中也会对齐家装修效果图卫生间进行解释,如果能碰巧解决你现在面临的问题,别忘了关注本站,现在开始吧!本文目录一览: 1、在哪里根据户型找装修效果图 2、齐家网装修平台可靠吗 3、齐家网装修公司怎么样?如何选择装修公司? 4、谁用过齐家网平台装修过呢?...

装修工程报价表(工程装修报价明细表)

装修工程报价表(工程装修报价明细表)

今天给各位分享装修工程报价表的知识,其中也会对工程装修报价明细表进行解释,如果能碰巧解决你现在面临的问题,别忘了关注本站,现在开始吧!本文目录一览: 1、装修工程报价单范本哪位有?都包括了哪些项目呢? 2、装修公司工程明细报价表出钱吗 3、装修报价中常见的几个坑 你遇到几个 4、新手必看...

王者荣耀的源码(王者荣耀源码曝光)

王者荣耀的源码(王者荣耀源码曝光)

今天给各位分享王者荣耀的源码的知识,其中也会对王者荣耀源码曝光进行解释,如果能碰巧解决你现在面临的问题,别忘了关注本站,现在开始吧!本文目录一览: 1、同一个王者荣耀帐号,安卓和苹果是否共用游戏时间 2、王者荣耀怎么自己做皮肤 3、为什么王者荣耀每次下载了还要更新,而不是直接可以登录账号?...