1. <output id="hzk7v"><pre id="hzk7v"><address id="hzk7v"></address></pre></output>
      <output id="hzk7v"></output>
    2. <nav id="hzk7v"><i id="hzk7v"><em id="hzk7v"></em></i></nav>
    3. <listing id="hzk7v"><delect id="hzk7v"><em id="hzk7v"></em></delect></listing>

      .net core并发下线程安全问题详解

       更新时间£º2019年04月11日 09:07:30   作者£ºVam8023   我要评论

      这篇文章主要给大家介绍了关于.net core并发下线程安全问题的相关资料£¬文中通过示例代码介绍的非常详细£¬对大家学习或者使用.net core具有一定的参考学习价值£¬需要的朋友们下面来一起学习学习吧

      抱歉£¬其实内容并不如题£¡£¡£¡

      背景£¨写测试demo所出现的异常£¬供大家学习与拍砖£©£º

      .net core webapi项目£¬做了一个授权的filter£¨真正的生产项目的话£¬JWT很棒£©£¬单个接口测试没有问题£¬当用前端在同一个页面调用多个接口的时候£¬运行服务£¬打开页面£¬然后¡­¡­Exceptions¡­¡­£¨真正的开发中大家应该?#19981;?#36935;到£©

      异常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£º不允许启动新事务£¬因为有其他线程正在?#27809;?#35805;中运行¡£

      异常7£ºAn error occurred while updating the entries. See the inner exception for details.

      尝试运行了N多遍£¬嗯£¬挺不稳定的£¨代码垃圾£¡£©£¬那看看异常吧

      一看很容易理解£º在前一个操作完成之前£¬在此上下文中启动第二个操作¡£任?#38382;?#20363;成员都不能保证是线程安全的¡£就是说£¬我在用这个上下文的时候£¬你来?#26639;?#23617;¡­¡­

      这个可能发生在并发的情况下£¬同时使用了同一个上下文¡­¡­那么打开一个页面£¬为什么会同时使用同一个上下文呢£¿好吧£¬在这里要负荆请罪了£¨可?#36816;?#26159;自己的问题£©

      我在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¡¢本来已经实例的对象被回收了¡­¡­£¨这可能?#26376;æ|­¡?#26377;一定的可能£¬但发生在哪呢£¿£©

      找啊找£¬其实方向有了£¬但是自己却没想起来¡­¡­

      其实如果不确定的话£¬倒是可以?#26085;?#25214;别人是怎?#27492;?#30340;£¨不是为了装X£¬找开发上的问题我是推荐 github 和 stackoverflow 的£¬大部分的问题都可以找到£©£º

      £¨1£©异常 1 还有同样 一条搜索结果

      £¨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£¬问题已经解决了£¬这是在开发中遇到的问题£¬可?#36816;µÊ巧?#21450;到.net core 本身的运行机制¡£

      我算是一个应用型的程序员£¬?#19981;对?#24212;用中学习底层的东西¡£那么接下来当然就可以扩展 Singleton¡¢Scoped 和 Transient 等知识了¡£

      总结

      以上就是这篇文章的全部内容了£¬希望本文的内容对大家的学习或者工作具有一定的参考学习价值£¬谢谢大家对脚本之家的支持¡£

      您可能?#34892;?#36259;的文章:

      相关文章

      最新评论

      3dÊÔ»úºÅÖвÊÍø

        1. <output id="hzk7v"><pre id="hzk7v"><address id="hzk7v"></address></pre></output>
          <output id="hzk7v"></output>
        2. <nav id="hzk7v"><i id="hzk7v"><em id="hzk7v"></em></i></nav>
        3. <listing id="hzk7v"><delect id="hzk7v"><em id="hzk7v"></em></delect></listing>

            1. <output id="hzk7v"><pre id="hzk7v"><address id="hzk7v"></address></pre></output>
              <output id="hzk7v"></output>
            2. <nav id="hzk7v"><i id="hzk7v"><em id="hzk7v"></em></i></nav>
            3. <listing id="hzk7v"><delect id="hzk7v"><em id="hzk7v"></em></delect></listing>