Threads(异步和多线程)(异步与多线程)

网友投稿 357 2022-06-21


Task是.NET Framework4.5出现的,线程是基于线程池的,然后提供丰富的api,Thread方法很多很强大,但是太过强大,没有限制。

DoSomethingLong方法如下:

Task的使用:

如果这样去调用:

如果去掉设置最大线程的代码:

运行结果如下:

ThreadPool.SetMaxThreads(8, 8);

线程池是单例的,全局唯一的,设置后,同时并发的Task只有8个,而且是复用的,Task的线程是源于线程池的,全局的,请不要这样设置。

假如我想控制下Task的并发数量,改怎么做?

运行结果如下:

如果将最后一个stopwatch注释掉:

什么时候用多线程?

任务并发是时候

多线程能干嘛?

提升速度,优化用户体验。

比如,现在有一个场景,在公司开会,领导在分配任务,不能并发,因为只能有一个领导在讲话分配任务,当任务分配下去,开发们确实可以同时开始撸代码,这个是可以并发的。

现在要求,谁第一个完成,获得红包奖励(ContinueWhenAny);所有完成后,一起庆祝下(ContinueWhenAll),将其放入一个List里面去

ContinueWhenAny  ContinueWhenAll 非阻塞式的回调;而且使用的线程可能是新线程,也可能是刚完成任务的线程,唯一不可能是主线程

Task.WaitAny  WaitAll都是阻塞当前线程,等任务完成后执行操作,阻塞卡界面,是为了并发以及顺序控制,网站首页:A数据库 B接口 C分布式服务 D搜索引擎,适合多线程并发,都完成后才能返回给用户,需要等待WaitAll,列表页:核心数据可能来自数据库/接口服务/分布式搜索引擎/缓存,多线程并发请求,哪个先完成就用哪个结果,其他的就不管了。

假如说我想控制下Task的并发数量,该怎么做?  20个

Parallel并发执行多个Action线程,主线程会参与计算---阻塞界面。等于TaskWaitAll+主线程计算

Parallel.Invoke(() => this.DoSomethingLong("btnParallel_Click_1"),

() => this.DoSomethingLong("btnParallel_Click_2"),

() => this.DoSomethingLong("btnParallel_Click_3"),

() => this.DoSomethingLong("btnParallel_Click_4"),

() => this.DoSomethingLong("btnParallel_Click_5"));

Parallel.For(0, 5, i => this.DoSomethingLong($"btnParallel_Click_{i}"));

Parallel.ForEach(new int[] { 0, 1, 2, 3, 4 }, i => this.DoSomethingLong($"btnParallel_Click_{i}"));

ParallelOptions options = new ParallelOptions();

options.MaxDegreeOfParallelism = 3;

Parallel.For(0, 10, options, i => this.DoSomethingLong($"btnParallel_Click_{i}"));

有没有办法不阻塞?

几乎90%以上的多线程场景,以及顺序控制,以上的Task的方法就可以完成,如果你的多线程场景太复杂搞不定,那么请梳理一下你的流程,简化一下。建议最好不要线程嵌套线程,两三次勉强能懂,三层就hold不住了,更多的只能求神。

多线程异常:

线程取消:

临时变量:

为什么运行结果后,都是5呢?

临时变量问题,线程是非阻塞的,延迟启动的;线程执行的时候,i已经是5了

那么该如何解决呢?

每次都声明一个变量k去接收,k是闭包里面的变量,每次循环都有一个独立的k,5个k变量  1个i变量

这样再运行,结果就正常了。

线程安全&lock:

线程安全:如果你的代码在进程中有多个线程同时运行这一段,如果每次运行的结果都跟单线程运行时的结果一致,那么就是线程安全的

线程安全问题一般都是有全局变量/共享变量/静态变量/硬盘文件/数据库的值,只要多线程都能访问和修改

发生是因为多个线程相同操作,出现了覆盖,怎么解决?

1 Lock解决多线程冲突

Lock是语法糖,Monitor.Enter,占据一个引用,别的线程就只能等着

推荐锁是private static readonly object,

A不能是Null,可以编译不能运行;

B 不推荐lock(this),外面如果也要用实例,就冲突了

共2页: 上一页12下一页


版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:表达式树练习实践:C# 循环与循环控制(树的表达方式)
下一篇:表达式树练习实践:入门基础
相关文章

 发表评论

暂时没有评论,来抢沙发吧~