多线程资源占用问题

1.常见的会引起资源冲突的

·文件系统资源:多个线程同时读取,写入或删除同一文件或目录时

·数据库资源: 多线程并发访问和修改同一数据库记录(缺乏事务控制或锁定机制),多个线程或进程使用数据库连接资源时,可能导致连接超时或连接耗尽。

·内存资源: 多线程同时访问或修改静态(全局)变量时可能引发竞争条件,导致数据不一致出错

·网络资源:同时范文或操作同一个网络套接字(如发送和接受数据)可能会引发冲突,导致数据包丢失或混乱;多个进程绑定同一端口等;

·硬件资源:多线程同时访问打印机,扫描仪可能会引起冲突。

·配置文件: 多线程同时读取或写入同一配置文件

·日志文件:多线程同时写入同一个日志文件

2.常用的解决资源冲突的方法

内存映射文件(内容映射到进程的虚拟地址中)、临时文件缓存(本地副本文件)、内存流(内存中(堆)划一块区域存储临时文件)

 //防止资源占用,使用内存流存储数据
 byte[] pixels;
 int width, height;
 using (Bitmap bitmap = new Bitmap(patientMsg.PicturePath))
 {
     width = bitmap.Width;  // 保存宽度信息
     height = bitmap.Height; // 保存高度信息

     using (MemoryStream ms = new MemoryStream())
     {
         bitmap.Save(ms, System.Drawing.Imaging.ImageFormat.Bmp); // 将图片保存到内存流
         pixels = ms.ToArray(); // 将图片数据转换为字节数组,传输和存储本地等方便,需要再转为bitmap
     }
 }


 MemoryByteBuffer buffer = new MemoryByteBuffer(pixels);

适用场景:文件系统资源

访问非常大的文件(如图像文件),如果是很小的文件,用锁就行了

通过async和await实现异步网络操作,在不阻塞主线程的情况下处理多个网络请求

适用场景: 网络资源,数据库资源

对于数据库资源可能存在的高并发访问的场景,应该使用数据库连接池会更好

 在Program.cs 配置

// 添加DbContext服务,配置连接池,可以应对高并发
      services.AddDbContextPool<AppDbContext>(options =>
    options.UseSqlServer(connectionString));

// 添加DbContext服务,不配置连接池
     services.AddDbContext<AppDbContext>(options =>
    options.UseSqlServer(connectionString));

适用场景:数据库资源

EFCore是实现了优秀的连接池管理

使用各种锁(互斥锁,读写锁)来禁止多线程同时访问同一资源

    static int sharedResource = 0;
    static readonly object mutex = new object();

    static void Increment()
    {
        for (int i = 0; i < 10000; i++)
        {
            lock (mutex)
            {
                sharedResource++;
            }
        }
    }

适用场景:内存资源

锁内的执行步骤应该较为简单,且执行不需要耗费太长时间。

 单例模式只有一个全局实例负责配置文件的操作,从而避免多个实例同时访问配置文件可能带来的竞争问题。

public class DicomLogger
    {
        private static readonly Lazy<DicomLogger> instance = new Lazy<DicomLogger>(() => new DicomLogger());
        private string logFilePath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Logs", "log.txt");//路径
        private DicomLogger()
        {
            string logDirectory = Path.GetDirectoryName(logFilePath);
            if (!Directory.Exists(logDirectory))
            {
                Directory.CreateDirectory(logDirectory);
            }
            Log.Logger = new LoggerConfiguration().MinimumLevel.Information().WriteTo.RollingFile(logFilePath).CreateLogger();
        }
    }



public class DicomConfigurationManager
    {
        private static readonly Lazy<DicomConfigurationManager> instance = new Lazy<DicomConfigurationManager>(() => new DicomConfigurationManager());      //仅首次访问instance实例化
        private DicomConfigData configData;
        private string pacsConfigFilePath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "PacsConfig.ini");
        private readonly object _lock = new object();

        private DicomConfigurationManager()
        {
            configData = LoadConfiguration() ?? new DicomConfigData();
        }
    }

适用场景:硬件资源、配置文件、日志文件

注意单例的实现方式。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值