由于框架限制需要保留同步方式(避免异步编程如 async/await),以下基于同步多线程编程,结合死锁预防和线程安全集合的策略,优化提供的代码以解决程序卡在 _HEATOFF 的问题

由于框架限制需要保留同步方式(避免异步编程如 async/await),以下基于同步多线程编程,结合死锁预防和线程安全集合的策略,优化提供的代码以解决程序卡在 _HEATOFF 的问题。

优化重点包括:

  • 统一锁顺序:打破循环等待,避免死锁。
  • 超时锁机制:使用 Monitor.TryEnter 防止无限阻塞。
  • 线程安全集合:将 ParameterMap 替换为 ConcurrentDictionary。
  • 合并硬件操作:使用 HEATONESTEPSET 减少锁和硬件调用。
  • 增强日志:添加详细日志定位问题。
  • 信号量控制:限制硬件并发访问。

以下是优化后的完整代码,保留同步方式,针对 _HEATRise、_HEATOFF、_HEATON、 _StartQuery、RateQuery 和 Write 方法进行改进。


优化后的完整代码

using System;
using System.Collections.Concurrent;
using System.Threading;

// 假设的硬件接口和日志类(根据原代码推测)
public class HardwareResult
{
    public string Error { get; set; }
    public Dictionary<string, object> ResultMap { get; } = new Dictionary<string, object>();
}

public class HeatBoardRealTimeState
{
    private readonly object _lock = new object();
    private double[] _tempValue = new double[4];
    private double[] _workStatus = new double[4];
    private string _error = "0000";

    public string Error
    {
        get => Interlocked.CompareExchange(ref _error, _error, _error);
        set => Interlocked.Exchange(ref _error, value);
    }

    public double[] TempValue
    {
        get
        {
            lock (_lock)
            {
                return (double[])_tempValue.Clone();
            }
        }
        set
        {
            lock (_lock)
            {
                _tempValue = (double[])value.Clone();
            }
        }
    }

    public double[] WorkStatus
    {
        get
        {
            lock (_lock)
            {
                return (double[])_workStatus.Clone();
            }
        }
        set
        {
            lock (_lock)
            {
                _workStatus = (double[])value.Clone();
            }
        }
    }
}

public class HeatBoard
{
    private readonly ConcurrentDictionary<string, object> ParameterMap = new ConcurrentDictionary<string, object>();
    private readonly object m_Hardware; // 假设的硬件接口
    private readonly string Name;
    private readonly string HeatBoardGroup;
    private readonly string HardwareInfo.HardwareName; // 假设的硬件信息
    private readonly ILog m_Log; // 假设的日志接口
    private readonly IFileLogger m_FileLogger; // 假设的文件日志接口
    private bool m_Looping;
    private bool m_Stop;
    private string errCode;
    private bool HeatComplete;
    private double[] PreHeatTemperature;
    private double PreHeatTemperatureTime;
    private bool isHeatexception1, isHeatexception2, isHeatexception3;
    private string LastErrorCode;
    private bool Changed;
    private bool FirstRate;
    private int ReadRate;
    private HardwareConnectStatus HardwareConnectStatus;
    private readonly System.Diagnostics.Stopwatch m_sp = new System.Diagnostics.Stopwatch();
    private readonly System.Diagnostics.Stopwatch m_heatsp = new System.Diagnostics.Stopwatch();
    private readonly HeatBoardRealTimeState HeatBoardRealTimeState = new HeatBoardRealTimeState();

    private static readonly Semaphore HardwareSemaphore = new Semaphore(1, 1); // 限制硬件并发访问

    public void StartQuery()
    {
        m_Log.Info($"{Name}.StartACQ");
        m_Looping = true;
        Thread.Sleep(1000); // 保留原逻辑的初始延迟
        Thread thr = new Thread(new ThreadStart(_StartQuery))
        {
            IsBackground = true
        };
        thr.Start();
    }

    private void _StartQuery()
    {
        if (m_Hardware == null)
        {
            Initialize();
            if (m_Hardware == null)
            {
                ErrExceptionGrad(UNFINDHARDWARE);
                return;
            }
        }
        if (!m_Hardware.Connected)
        {
            ErrExceptionGrad(UNCONNECTIONHARDWARE);
            return;
        }
        m_Looping = true;

        while (!m_Stop && m_Hardware.Connected && SinySystem.InterLock == 0)
        {
            RateQuery();
            ReadRate = Convert.ToInt32(ParameterMap.TryGetValue("ReadRate", out var value) ? value : 1000);
            if (SinySystem.InterLock != 0)
            {
                break;
            }
            Thread.Sleep(ReadRate);
        }
        m_Looping = false;
    }

    private void RateQuery()
    {
        try
        {
            HardwareResult hardwareResult = new HardwareResult();
            string com = HardwareInfo.HardwareName.Split(',')[0];
            m_Log.Info($"Thread {Thread.CurrentThread.ManagedThreadId}: Attempting to acquire locks for {Name}, Group={HeatBoardGroup}, Com={com}");

            // 固定锁顺序:先 HeatBoardLockers,再 HdLockers
            lock (HardwareMgr.HeatBoardLockers[HeatBoardGroup])
            {
                if (!Monitor.TryEnter(IoMgr.HdLockers[com], 5000))
                {
                    m_Log.Error($"Thread {Thread.CurrentThread.ManagedThreadId}: Lock timeout for {com} in RateQuery");
                    throw new TimeoutException("Lock timeout");
                }
                try
                {
                    string heatBoardEnable = ParameterMap.TryGetValue("HeatBoardEnbale", out var value)
                        ? value.ToString()
                        : "0,0,0,0";
                    string instrction = $"HEATREAD HeatBoardEnbale={heatBoardEnable}";
                    m_Log.Info($"Thread {Thread.CurrentThread.ManagedThreadId}: Querying {instrction} for {Name}");
                    hardwareResult = m_Hardware.QueryData(instrction) as HardwareResult;
                }
                finally
                {
                    Monitor.Exit(IoMgr.HdLockers[com]);
                    m_Log.Info($"Thread {Thread.CurrentThread.ManagedThreadId}: Released lock for {com} in RateQuery");
                }
            }

            Changed = LastErrorCode != hardwareResult.Error.ToString();
            LastErrorCode = hardwareResult.Error.ToString();
            if (hardwareResult.Error.ToString() == "0000")
            {
                if (Changed || HardwareConnectStatus == HardwareConnectStatus.Malfunction)
                {
                    if (HardwareConnectStatus != HardwareConnectStatus.InUsing)
                    {
                        HardwareConnectStatus = HardwareConnectStatus.InUsing;
                    }
                }

                HeatBoardRealTimeState.Error = hardwareResult.Error.ToString();
                HeatBoardRealTimeState.TempValue = (double[])hardwareResult.ResultMap["TempValue"];

                double readCompensate = ParameterMap.TryGetValue("ReadCompensate", out var comp)
                    ? Convert.ToDouble(comp)
                    : RuntimeConfiguration.ReadCompensate;

                var tempValues = HeatBoardRealTimeState.TempValue;
                for (int i = 0; i < 4; i++)
                {
                    tempValues[i] += readCompensate;
                }
                HeatBoardRealTimeState.TempValue = tempValue
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

张工在路上

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值