一次Task.Run异常问题的排查

        最近在测试一个功能代码时发现一个非常奇怪的问题,主要是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

如果你想了解某方面的知识或文章可以把想法发送到

henryfan@msn.com|admin@beetlex.io

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/305934.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

git maven 一键部署_Jenkins Git Maven搭建自动化部署项目环境 邮件通知

简介折腾了两个晚上&#xff0c;趁着今晚比较有空&#xff0c;把jenkinsgitmaven搭建自动化部署项目环境搭建的过程记录一下,这里我把github作为git的远程仓库(https://github.com/jacky- lulu/cxf_demo-Maven-Webapp)系统&#xff1a;centos6.5maven: Apache Maven 3.3…

在.NET Core 中收集数据的几种方式

APM是一种应用性能监控工具&#xff0c;可以帮助理解系统行为, 用于分析性能问题的工具&#xff0c;以便发生故障的时候&#xff0c;能够快速定位和解决问题, 通过汇聚业务系统各处理环节的实时数据&#xff0c;分析业务系统各事务处理的交易路径和处理时间&#xff0c;实现对应…

java 连接池连接mysql数据库需要哪些jar包_DBCP-基于Java8导入DBCP连接池所需JAR包并编写DBCPUtils工具类...

上述五个jar包缺一不可下载解压后,进入解压出的文件夹将这五个jar包复制出来放入自己创建的myJar文件夹中(myJar文件夹创建与说明)接下来就可以在工程中进行使用package utils;import com.mysql.cj.jdbc.Driver;import org.apache.commons.dbcp2.BasicDataSource;import java.s…

C# 在自定义的控制台输出重定向类中整合调用方信息

C# 在自定义的控制台输出重定向类中整合调用方信息目录C# 在自定义的控制台输出重定向类中整合调用方信息一、前言二、输出重定向基础版三、输出重定向进阶版&#xff08;传递调用方信息&#xff09;四、后记及资源独立观察员 2021 年 1 月 6 日一、前言众所周知&#xff0c;在…

mac 上mysql怎么卸载不了_mac的mysql怎么卸载?

Mac下卸载mysql的方法&#xff1a;1、关闭mysql查看mysql是否启动&#xff1a;ps -ef |grep mysql输入&#xff1a;kill -9 (./mysqld前面第二个数字&#xff0c;这里是627) 然后回车&#xff0c;关闭mysql。2、卸载&#xff1a;在Mac终端使用下面的命令删除所有mysql文件即可s…

C#实现网页加载后将页面截取成长图片

背景最近再做一个需求&#xff0c;需要对网页生成预览图&#xff0c;如下图但是网页千千万&#xff0c;总不能一个个打开&#xff0c;截图吧&#xff1b;于是想着能不能使用代码来实现网页的截图。其实要实现这个功能&#xff0c;无非就是要么实现一个仿真浏览器&#xff0c;要…

“既然计划没有变化快,那制订计划还有个卵用啊!”

这是头哥侃码的第229篇原创每年年初&#xff0c;我的朋友圈里都会炸出不少在打完鸡血之后&#xff0c;迫不及待向全世界宣告自己 “新年Flag” 的人。有的人&#xff0c;把健身、养生设为目标&#xff0c;什么不暴瘦20斤不换头像呀&#xff0c;什么再也不吃炸鸡啤酒啦&#xff…

图书管理系统jsp代码_【程序源代码】使用Java开发的图书管理系统

关键字&#xff1a;java 管理系统 正文 | 内容01—【概述】使用Java开发的图书管理系统&#xff0c;读者可以注册登录&#xff0c;登录时会判断账号类型再分别跳到各自对应的页面&#xff0c;读者可以查找&#xff0c;借阅&#xff0c;还书&#xff0c;查看历史借阅记录&#x…

整合.NET WebAPI和 Vuejs——在.NET单体应用中使用 Vuejs 和 ElementUI

.NET简介.NET 是一种用于构建多种应用的免费开源开发平台&#xff0c;例如&#xff1a;Web 应用、Web API 和微服务云中的无服务器函数云原生应用移动应用桌面应用1). Windows WPF2). Windows 窗体3). 通用 Windows 平台 (UWP)游戏物联网 (IoT)机器学习控制台应用Windows 服务跨…

【gRPC】 在.Net core中使用gRPC

最近在学习.net core的微服务体系架构。微服务之间的通信常常通过gRPC进行同步通信&#xff0c;但是需要注意的是&#xff0c;大多数微服务之间的通信是通过事件总线进行异步通信。在微软介绍.net微服务体系架构的项目eShop中&#xff0c;微服务之间进行同步通信的场景很多&…

disconf mysql_Docker搭建disconf环境,三部曲之三:细说搭建过程

Docker下的disconf实战全文链接细说搭建过程在前两章中&#xff0c;我们利用远程或本地的镜像&#xff0c;快速体验了本地启动disconf的过程&#xff0c;本章我们一起来分析和梳理整个定制和搭建过程&#xff0c;了解这些后&#xff0c;我们就能根据自己的需要来定制本地的disc…

轻量级 Kubernetes K3s - Github热点

轻量级 Kubernetes k3sstar: 15.5kK3s是完全符合生产要求的Kubernetes发行版, 安装简单&#xff0c;可用于生产&#xff0c;整个二进制文件小于100M&#xff0c;作为单一文件打包部署&#xff0c;优势在于&#xff0c;你只需几秒钟就可以得到一个完全成熟的Kubernetes集群。htt…

java 固定长度队列_如何彻底搞懂 Java 数据结构?|CSDN 博文精选

作者 | 张振华.Jack责编 | 郭芮出品 | CSDN 博客本文和大家一起来重温《Java数据结构》经典之作。Java数据结构要理解Java数据结构&#xff0c;必须能清楚何为数据结构&#xff1f;数据结构&#xff1a;Data_Structure&#xff0c;它是储存数据的一种结构体&#xff0c;在此结构…

IdentityServer4 之 Resource Owner Password Credentials 其实有点尴尬

前言接着IdentityServer4的授权模式继续聊&#xff0c;这篇来说说 Resource Owner Password Credentials授权模式&#xff0c;这种模式在实际应用场景中使用的并不多&#xff0c;只怪其太开放啦&#xff0c;直接在客户端上拿着用户名和密码就去授权服务器获取AccessToken&#…

Xamarin使XRPC实现接口/委托远程调用

在之前的文章中已经介绍如何使用Beetlex.XRCP组件进行接口/委托远程调用&#xff1b;由于组件BeetleX.XRPC.Clients支持.NETStandard2&#xff0c;因此Xamarin同样可以使用它来实现基于接口/委托的数据交互通讯。接下来通过Xamarin实现一个简单的移动程序&#xff0c;并通过XRP…

mysql 拷贝安装_Mysql的安装和主从复制

安装mysql服务步骤一&#xff1a;首先下载mysql的yum源配置 &#xff0c;下载mysql的yum源wget http://dev.mysql.com/get/mysql57-community-release-el7-11.noarch.rpm步骤二&#xff1a;安装mysql的yum源yum -y install mysql57-community-release-el7-11.noarch.rpm步骤三&…

浅谈CLR基础知识

中午的时候&#xff0c;有一个小伙伴问我&#xff0c;CLR到底是进程还是线程&#xff0c;它和自己写的程序是怎么关联的。这一问&#xff0c;直接把我问懞了。下面我尝试用简单的语言来描述这个问题&#xff0c;有的地方无法讲的太细&#xff08;不然内容会太多&#xff09;&am…

Asp.Net Core使用Skywalking实现分布式链路追踪

介绍Skywalking 是 Apache 基金会下面的一个开源 APM 项目&#xff0c;是一套(APM)分布式追踪系统&#xff0c;提供了很多数据存储列如&#xff1a;Mysql&#xff0c;H2&#xff0c;Elasticsearch7 等。其中APM 全称是应用性能监测软件&#xff0c;主要是用来处理以及追踪分布式…

python 里什么时候缩进_python什么时候缩进

Python中的缩进(Indentation)决定了代码的作用域范围。这一点和传统的c/c有很大的不同(传统的c/c使用花括号花括号{}符决定作用域的范围&#xff1b;python使用缩进空格来表示作用域的范围&#xff0c;相同缩进行的代码是处于同一范围)。每行代码中开头的空格数(whitespace)用于…

C# 9 新特性 —— 补充篇

C# 9 新特性 —— 补充篇Intro前面我们分别介绍了一些 C# 9 中的新特性&#xff0c;还有一些我觉得需要了解一下的新特性&#xff0c;写一篇作为补充。Top-Level Statements在以往的代码里&#xff0c;一个应用程序必须要有 Main 方法才能运行&#xff0c;从 C# 9 开始&#xf…