RestSharp组件中止线程问题

发布时间 2023-04-13 11:54:49作者: o李一波o

 

 

背景:下单流程里面,生成发货单是在独立线程池完成的,有些批发订单数据巨大,频繁拆包生成多个发货单

排查:由于ES刷新是在一个独立的api里面,一开始怀疑是异步线程频繁请求api导致中断的

  • SemaphoreSlim:对同时访问资源或资源池的线程数加以限制,结果:无效
  • lock:顺序执行,使线程等待,结果:无效
  • 日记调试:在api里面打上日记,发现中止线程的时候根本没有进入api,现在基本可以断定是调用端的问题
    查看调用端代码
// 改造前
//var client = new RestClient($"{ElasticsearchBaseApi}/api/Elasticsearch/UpdateElasticsearchOrder");
//var resp = client.Execute(request);

// 改造后(使用单例/静态变量)
var resp = client.Execute(request);

发现该项目好多地方都习惯是直接new一个RestClient来使用,正常业务量不大的时候是没问题的,如果业务量大了这里就会导致线程数过高最终导致线程中止

延伸:静态变量与单例

静态变量:众所周知静态变量只会初始化一次,声明时开辟内存空间知道程序结束,所有单例共享该空间
单例:所有实例指针地址都是同一个,是同一块内存空间
测试:

using System;

namespace ERP.JK.Util
{
    class Student
    {
        private static Student _Instance;
        public static Student Instance
        {
            get
            {
                if (_Instance==null)
                {
                    _Instance = new Student();
                }
                return _Instance;
            }
        }
        public int Age;
    }
    class Program
    {
        private static Student student = new Student();
        private static Student student2 = new Student();
        static void Main(string[] args)
        {
            try
            {
                Student s1 = Student.Instance;
                s1.Age = 10;
                unsafe
                {
                    fixed (int* p = &s1.Age)
                    {
                        Console.WriteLine("Address:0x{0:x},value:{1}", (int)p,s1.Age);
                    }
                }
                Student s2 = Student.Instance;
                s1.Age = 20;
                unsafe
                {
                    fixed (int* p = &s2.Age)
                    {
                        Console.WriteLine("Address:0x{0:x},value:{1}", (int)p, s2.Age);
                    }
                }

                student.Age = 30;
                unsafe
                {
                    fixed (int* p = &student.Age)
                    {
                        Console.WriteLine("Address:0x{0:x},value:{1}", (int)p, student.Age);
                    }
                }

                student2.Age = 40;
                unsafe
                {
                    fixed (int* p = &student2.Age)
                    {
                        Console.WriteLine("Address:0x{0:x},value:{1}", (int)p, student2.Age);
                    }
                }

            }
            catch (Exception ex)
            {
                throw ex;
            }
        }
    }
}

运行结果:

  • 可以看出s1,s2里面的Aage地址都是一样的
  • student 与student2 因为分别实例并且存储在静态变量中,所以地址不一样