建设信用卡登录中心网站,彩票的网站怎么做的,wordpress清空文章备份并对齐id,北京高端网站建设系统最近在测试一个功能代码时发现一个非常奇怪的问题#xff0c;主要是Task.Run引起一些不符合逻辑的错误#xff0c;以下针对这一问题排查的总结。问题代码可以建个控制台程序来运行以下代码class Program{static User user new User();static void Main(string[] args){for (… 最近在测试一个功能代码时发现一个非常奇怪的问题主要是Task.Run引起一些不符合逻辑的错误以下针对这一问题排查的总结。问题代码 可以建个控制台程序来运行以下代码 class Program{static User user new User();static void Main(string[] args){for (int i 0; i 50; i){Task.Run(user.Init);}System.Threading.Thread.Sleep(-1);}}public class User{private bool mInit false;private Task OnInit(){Console.WriteLine(User init);System.Threading.Thread.Sleep(1000);return Task.CompletedTask;}public void Init(){lock (typeof(User)){if (!mInit){var task Task.Run(this.OnInit);if (!task.Wait(5000)){throw new TimeoutException(user init error!);}mInit true;}}}}
以上代码执行的结果非常奇怪当在Debug模式下运行会抛出超时错误。运行在release模式下则会引起OnIint方法被执行多次lock完全起不了作用。。和朋友讨论过程中说lock不要和Task.Run混用但Task.Wait的实现是基于线程信号量的和async/await是有着本质的差异。抱着解决问题的思路把Task.Run直接改成了线程池方式运行但结果还是一样。由于找不到问题原因最终去dotnet上提个issues看一下能提供什么意见。问题的发现 对于一个程序员来说问题没解决怎能安心呢隔一天issues没有响应于是开启的解决问题的碰撞模式。在throw timeout里打个断点看一下情况结果无意中发现Task的状态是WaitingForActivation状态描述是等待内部调度激活意思是说这代码并不是不执行或执行有问题而因为某些状态导致Task还在等待执行中。然后针对这一问题在网查找了一下才发现这问题的原因主要问题是for 50已经把线和池中的线程抽光了然然后在Init方法使用Task.Run的时候就只能等待。。。加上方法后面Task.Wait导致当前线程无法回归到池所以就只能引起超时间异常如果这里的Task.Wait不加上个超时那这测试代码就直接处于假死状态无法继续工作一个等待一个试图获取线程操作从而形成一个类似于死锁的问题总结 当你在使用Task.Run时出现一些非常意想不到的结果时可以通过Task.Status状态可以更好的定位到问题。Task默认也是基于线程池的所以在使用Task.Run和Task.Wait的就要注意这一点虽然可以通过加大线程池的最小数量来解决低并发问题但高并发下还是会存在线程资源不足的情况为了确保不出现类似于死锁的问题请在使用Task.Wait必须加上超时时间,并且是越短越好毕竟Wait方法是基于线程阻塞。BeetleX开源跨平台通讯框架(支持TLS)轻松实现高性能:tcp、http、websocket、redis、rpc和网关等服务应用https://beetlex.io如果你想了解某方面的知识或文章可以把想法发送到henryfanmsn.com|adminbeetlex.io