当前位置 博文首页 > bindot:CPU 100% 问题分析,我们把博客园踩过的坑又踩了一遍《

    bindot:CPU 100% 问题分析,我们把博客园踩过的坑又踩了一遍《

    作者:bindot 时间:2021-02-02 18:23

    StackExchange.Redis.RedisConnectionException: It was not possible to connect to the redis server(s); to create a disconnected multiplexer, disable AbortOnConnectFail. Timeout There is already an open DataReader associated with this Command which must be closed first A second operation started on this context before a previous operation completed. This is usually caused by different threads using the same instance of DbContext, however instance members are not guaranteed to be

    问题如下:

    针对.net core 异常奇怪问题分析

    • cpu 和内存不高,但是线上系统运行很卡
    • cpu使用率瞬时升高,甚至突破100%(负载突然升高)
    • 其它服务(或者进程外的资源)传入负载能力超出(或提示连接超时),比如提示(StackExchange.Redis.RedisConnectionException: It was not possible to connect to the redis server(s); to create a disconnected multiplexer, disable AbortOnConnectFail. Timeout at StackExchange.Redis.ConnectionMultiplexer.ConnectImpl(Func`1 multiplexerFactory, TextWriter log))
    • 也可能是一次显示为"较长"的数据库查询
    • 或者任何非cpu活动(如任何I/O或延迟),因此似乎非常I/O 操作随机需要的时间比它应该需要的时间长
    • 线程数莫名奇妙的不断升高

    1、StackExchange.Redis.RedisConnectionException: It was not possible to connect to the redis server(s); to create a disconnected multiplexer, disable AbortOnConnectFail. Timeout
    at StackExchange.Redis.ConnectionMultiplexer.ConnectImpl(Func`1 multiplexerFactory, TextWriter log)

    2、There is already an open DataReader associated with this Command which must be closed first

    3、A second operation started on this context before a previous operation completed. This is usually caused by different threads using the same instance of DbContext, however instance members are not guaranteed to be

    static void Main(string[] args)
            {
              //按键后开始执行
                Console.ReadKey();
                //模拟并发
                while (true)
                {
                    Task.Run(Producer);
                    Thread.Sleep(200);
                }
               
            }
            /// <summary>
            /// 如果处理程序耗时>请求耗时,也就是说引起并发,就会导致死锁
            /// </summary>
            static void Producer()
            {
                var result = Process().Result;
                //或者
                //Process().Wait();
            }
    
    
            static async Task<bool> Process()
            {
                Console.WriteLine("Start - " + DateTime.Now.ToLongTimeString());
                await Task.Run(() =>
                {
                    //模拟任务执行耗时
                    Thread.Sleep(1000);
                });
    
                Console.WriteLine("Ended - " + DateTime.Now.ToLongTimeString());
                return true;
            }        

     

    执行效果:

    以上可看出:

    1、控制台执行5-10个任务后,不再执行Ended 语句的任何内容(Ended语句全部被阻塞)

    2、内存占用稳步上升

    3、AsyncTest.exe 线程每秒增加一个

     

    解决方案:

    var result = Process().ConfigureAwait(false);

    或修改为异步方法

         static async Task Producer()
            {
                await Process();
            }

     

     

    参考:

    又踩.NET Core的坑:在同步方法中调用异步方法Wait时发生死锁(deadlock)

    一码阻塞,万码等待:ASP.NET Core 同步方法调用异步方法“死锁”的真相

    .NET Core中遇到奇怪的线程死锁问题:内存与线程数不停地增长

     C#同步方法中如何调用异步方法?值得一看

     理解C#中的ConfigureAwait

     bindot:https://www.cnblogs.com/bindot/p/cpu100.html

    bk