.net core 并发下的线程安全问题
抱歉,其实内容并不如题!!!真正的题目应该为《.net core 并发下由于注入模式引起的线程安全问题》
背景(写测试demo所出现的异常,供大家学习与拍砖):
.net core webapi项目,做了一个授权的filter(真正的生产项目的话,JWT很棒),单个接口测试没有问题,当用前端在同一个页面调用多个接口的时候,运行服务,打开页面,然后……Exceptions……(真正的开发中大家应该也会遇到)
异常1:An attempt was made to use the context while it is being configured. A DbContext instance cannot be used inside OnConfiguring since it is still being configured at this point. This can happen if a second operation is started on this context before a previous operation completed. Any instance members are not guaranteed to be thread safe.
异常2:A second operation started on this context before a previous operation completed. Any instance members are not guaranteed to be thread safe.
异常3:Invalid attempt to call Read when reader is closed.
异常4:Unable to cast object of type 'System.Data.ProviderBase.DbConnectionClosedConnecting' to type 'System.Data.SqlClient.SqlInternalConnectionTds'.
异常5:Object reference not set to an instance of an object.
异常6:不允许启动新事务,因为有其他线程正在该会话中运行。
异常7:An error occurred while updating the entries. See the inner exception for details.
尝试运行了N多遍,嗯,挺不稳定的(代码垃圾!),那看看异常吧
一看很容易理解:在前一个操作完成之前,在此上下文中启动第二个操作。任何实例成员都不能保证是线程安全的。就是说,我在用这个上下文的时候,你来抢个屁……
这个可能发生在并发的情况下,同时使用了同一个上下文……那么打开一个页面,为什么会同时使用同一个上下文呢?好吧,在这里要负荆请罪了(可以说是自己的问题)
我在Filter里面有查询,用到数据库上下文<DbContext> 。罪过咯,直接想在Filter里面过滤黑名单,所以查了数据库(这个业务是不合理的,这是一个作死的行为,请谨慎看待,这里做学习讨论之用)。
public class AuthFilterAttribute : ActionFilterAttribute
{ public override void OnActionExecuting(ActionExecutingContext context)
{ base.OnActionExecuting(context);
..... //判断是否在黑名单内
var blackList = _app.GetBlackList();
......
}
}
这里为什么用 ActionFilterAttribute ?是因为测试的时候要监测一下接口运行的整个过程,So……
然后还有一些错是:对象引用未设置为对象的实例。这个错误太常见,不就是对象为Null了吗?但是,未实例化对象在业务逻辑上的情况太多了。我的应该有:
1、没有获取到当前对象,这是.net core,不是.net,不是因为没有new对象。是注入中没有注入成功,获取注入后,没有获取到。(但我本来运行的好好的,是因为一下是打开对接的页面才发生的问题,可以排除了)
2、本来已经实例的对象被回收了……(这可能性嘛……有一定的可能,但发生在哪呢?)
找啊找,其实方向有了,但是自己却没想起来……
其实如果不确定的话,倒是可以先找找别人是怎么说的(不是为了装X,找开发上的问题我是推荐 github 和 stackoverflow 的,大部分的问题都可以找到):


(2)异常 2

虽然以上找的不一定是真正的答案,至少提供了一个方向,并且你至少可以尝试性地去解决一下。这里提供的方向其实很明确:
1、是否应该使用 Scoped 和 Transient 的,你却使用了 Singleton;
2、多线程中使用了 async 却没有配对的使用 await;
至少我找到的关键点是这两个。
那怎么找到并解决这个问题呢,.net core都是注入的,当然 AuthFilterAttribute 也是注入的。跑到 Startup一看,很明显,问题出在哪里了 -- 单例!本应该是Scoped模式的,却用了单例。
那就将 AuthFilterAttribute 换一种注入模式就行啦。

改为

我使用的是Filter,Filter有自己的生命周期,去确认一下:Filter的官方文档
看到一张图!!!(当然你也可以细细研读一下这个文档)如下:

这还不明显?!!!
Filter会被回收的!!!这同样解释了 异常3、4、5、6、7所发生的原因。
OK,问题已经解决了,这是在开发中遇到的问题,可以说是涉及到.net core 本身的运行机制。
我算是一个应用型的程序员,喜欢在应用中学习底层的东西。那么接下来当然就可以扩展 Singleton、Scoped 和 Transient 等知识了。
如不喜,请拍!
.net core 并发下的线程安全问题的更多相关文章
- Core Data 的线程安全问题
前言: 很多小的App只需要一个ManagedContext在主线程就可以了,但是有时候对于CoreData的操作要耗时很久的,比如App开启的时候要载入大量数据,如果都放在主线程,毫无疑问会阻塞UI ...
- ios 单一线程中的Runloop机制会导致线程安全问题吗?
今天在处理多线程突然想到一个问题,多核处理器会不会导致,单一线程中,由runloop分发的2个函数同时执行呢?进而同时修改同一个变量,产生bug? 我做了以下的测试: - (void)viewDidL ...
- Java并发编程基础-线程安全问题及JMM(volatile)
什么情况下应该使用多线程 : 线程出现的目的是什么?解决进程中多任务的实时性问题?其实简单来说,也就是解决“阻塞”的问题,阻塞的意思就是程序运行到某个函数或过程后等待某些事件发生而暂时停止 CPU 占 ...
- ASP.NET MVC深入浅出系列(持续更新) ORM系列之Entity FrameWork详解(持续更新) 第十六节:语法总结(3)(C#6.0和C#7.0新语法) 第三节:深度剖析各类数据结构(Array、List、Queue、Stack)及线程安全问题和yeild关键字 各种通讯连接方式 设计模式篇 第十二节: 总结Quartz.Net几种部署模式(IIS、Exe、服务部署【借
ASP.NET MVC深入浅出系列(持续更新) 一. ASP.NET体系 从事.Net开发以来,最先接触的Web开发框架是Asp.Net WebForm,该框架高度封装,为了隐藏Http的无状态模 ...
- SimpleDateFormat类的线程安全问题和解决方案
摘要:我们就一起看下在高并发下SimpleDateFormat类为何会出现安全问题,以及如何解决SimpleDateFormat类的安全问题. 本文分享自华为云社区<SimpleDateForm ...
- 被我们忽略的HttpSession线程安全问题
1. 背景 最近在读<Java concurrency in practice>(Java并发实战),其中1.4节提到了Java web的线程安全问题时有如下一段话: Servlets a ...
- Java多线程--线程安全问题的相关研究
在刚刚学线程的时候我们经常会碰到这么一个问题:模拟火车站售票窗口售票.代码如下: package cn.blogs.com.isole; /* 模拟火车站售票窗口售票,假设有50张余票 */ publ ...
- struts2学习笔记--线程安全问题小结
在说struts2的线程安全之前,先说一下,什么是线程安全?这是一个网友讲的, 如果你的代码所在的进程中有多个线程在同时运行,而这些线程可能会同时运行这段代码.如果每次运行结果和单线程运行的结果是一样 ...
- iOS中的线程安全问题
为了保证线程安全,不会因为多个线程访问造成资源抢夺,出现的运行结果的偏差问题,我们需要使用到线程同步技术,最常用的就是 @synchronized互斥锁(同步锁).NSLock.dispatch_se ...
随机推荐
- Java单例模式(Singleton)以及实现
一. 什么是单例模式 因程序需要,有时我们只需要某个类同时保留一个对象,不希望有更多对象,此时,我们则应考虑单例模式的设计. 二. 单例模式的特点 1. 单例模式只能有一个实例. 2. 单例类必须创建 ...
- Java学习导航
由于最近在系统的重新学习Java,为了便于日后复习,给个人博客中Java内容做一个目录. Java基础:Java虚拟机(JVM) Java基础:内存模型 Java基础:JVM垃圾回收算法 Java基础 ...
- 进阶-Redis 知识梳理
redis介绍 1.什么是NoSQL NoSQL(统称),泛指非关系型的数据库,NoSQL即Not-Only SQL,它可以作为关系型数据库的良好补充. 2.NoSQL数据库的四大分类如下: 键值(K ...
- AbstractQueuedSynchronizer原理及代码分析
一.AQS简介 AbstractQueuedSynchronizer(AQS)是java.util.concurrent并发包下最基本的同步器,其它同步器实现,如ReentrantLock类,Reen ...
- linux独有的sendfile系统调用--“零拷贝,高效”
参考:http://blog.csdn.net/caianye/article/details/7576198 如今几乎每个人都听说过Linux中所谓的"零拷贝"特性,然而我经常碰 ...
- Graphviz--图形绘制工具
可以试试ProcessOn.com, 一个专业在线画流程图的工具,使用Chrome&Firefox浏览器,支持快捷键,非常方便.快捷键如下:Ctrl+A 全选,当移动整张图时非常方便Ctrl+ ...
- 聊聊Spring Cloud版本的那些事儿
说说Spring Cloud版本的那些事儿. 版本命名 之前提到过,Spring Cloud是一个拥有诸多子项目的大型综合项目,原则上其子项目也都维护着自己的发布版本号.那么每一个Spring Clo ...
- 关于多条数据转为json格式单次传输的问题 2017.05.27
数据形式如下: var mycars = [];//定义数组存放多条数据 for(var i=0;i<2;i++){ var jsonData = {};//定义变量存放单条数据 jsonDat ...
- const命令,全局变量的属性,变量的解构赋值
const命令 1:声明常量(只在当前代码块中有效)---注意声明的常量可以是对象,但是常量储存的是对象的地址,地址声明后不可变,但是可以给常量对象添加属性 全局变量的属性 1:window和glob ...
- Volley 图片加载相关源码解析
转载请标明出处: http://blog.csdn.net/lmj623565791/article/details/47721631: 本文出自:[张鸿洋的博客] 一 概述 最近在完善图片加载方面的 ...