对象引用未设置为对象 System.IO.Ports 的实例

Object reference not set to an instance of an object System.IO.Ports

提问人:Akbarali Otakhanov 提问时间:9/7/2023 更新时间:9/7/2023 访问量:41

问:

我们使用 LattePanda 在 .Net Framework 上创建了一个桌面应用程序,以使用 RS485 通信协议从 PCB 读取传感器数据。在 c# 部分,我们使用了 EasyModbus 库来读取数据。该应用程序在某种程度上运行良好,但在某些时候它抛出以下错误:

Object reference not set to an instance of an object.   
at System.IO.Ports.SerialStream.EventLoopRunner.CallReceiveEvents(Object state)
at System.Threading.QueueUserWorkItemCallback.Execute()
at System.Threading.ThreadPoolWorkQueue.Dispatch()
at System.Threading.PortableThreadPool.WorkerThread.WorkerThreadStart()

在下面的文章中,您可以看到用于创建 ModbusClient 对象和 ReadInputRegisters() 方法的 c# 代码。我们找不到终止的原因。

private readonly SemaphoreSlim _lock = new (1, 1);

    private static ModbusClient CreateAndConnectClient(string comPort, int baudrate, byte unitIdentifier)
    {
        try
        {
            ModbusClient modbusClient = new(comPort)
            {
                UnitIdentifier = unitIdentifier,
                Baudrate = baudrate,
                Parity = Parity.None,
                StopBits = StopBits.One,
                ConnectionTimeout = 1000
            };
            modbusClient.Connect();
            return modbusClient;

        }
        catch (ModbusException ex) {
            Trace.WriteLine("ModbusException: " + ex.Message);
            throw; 
        }
        catch (Exception ex)
        {
            Trace.WriteLine("Unhandled Exception: " + ex.Message);
            throw;
        }
    }

    public async Task<int[]> ReadInputRegistersAsync(string comPort, int baudrate,  byte unitIdentifier, int startAddress, int quantity)
    {
        await _lock.WaitAsync();
        ModbusClient? modbusClient = null;
        try
        {
            // Attempt to create and connect the Modbus client
            modbusClient = CreateAndConnectClient(comPort, baudrate, unitIdentifier);


            // Check if the client was successfully created and connected
            // to avoid Exception --> "Object reference not set to an instance of an object" 
            if (modbusClient == null)
            {
                Trace.WriteLine("ModbusClient is null.");
                return new int[quantity];
            }

            var data = modbusClient.ReadInputRegisters(startAddress, quantity) ?? new int[quantity];
            return data;
            
        }
        catch (ModbusException ex)
        {
            Trace.WriteLine("ModbusException in ReadInputRegistersAsync: " + ex.Message);

            // Return a new empty integer array
            return new int[quantity];
        }

        catch (Exception ex)
        {
            Trace.WriteLine("Unhandled Exception in ReadInputRegistersAsync: " + ex.Message);
            return new int[quantity];
        }

        finally
        {
            if (modbusClient!=null && modbusClient.Connected)
            {
                modbusClient.Disconnect();
            }
            _lock.Release();
        }
    }

然后在下面的类中,我们调用了 ReadInputRegistersAsync()

public List<RawInput> GetData(DateTime date)
        {
            var data = new List<RawInput>();
            var items = GetSensors();
            var groupeItems = items.GroupBy(i => i.SlaveID).ToList();

            foreach (var itemGroup in groupeItems)
            {
                var sensors = itemGroup.ToList();
                var sensor = sensors.OrderBy(i => i.InputCh).LastOrDefault();
                if (sensor == null) continue;
                var readTask = modbusManager.ReadInputRegistersAsync(
                    $"COM{sensor.SerPort}", 9600, (byte)itemGroup.Key, 0, sensor.InputCh);
                Trace.WriteLine("^^^^^^^^^^^^^^^^^^^ READ TASK SlaveID: " + (byte)itemGroup.Key);
                readTask.ContinueWith(task =>
                {
                    if (task.IsCompletedSuccessfully)
                    {
                        var list = task.Result.ToList();
                        data.AddRange(sensors.ConvertAll(s =>
                            new RawInput()
                            {
                                ItemId = s.Id,
                                RawValue = list[s.InputCh - 1]
                            }
                        ));
                    }
                    else
                    {
                        Trace.WriteLine("^^^^^^^^^^^^^^^^^^^ READ TASK IS NOT COMPLETED SUCCESSFULLY");
                        data.AddRange(sensors.ConvertAll(s => new RawInput()
                        {
                            ItemId = s.Id,
                            RawValue = 0
                        }));
                    }

                }).Wait();
            }

            return data;
        }
.net 端口 modbus system.io.file

评论

0赞 Filburt 9/7/2023
这回答了你的问题吗?什么是 NullReferenceException,如何修复它?
0赞 Akbarali Otakhanov 9/7/2023
我已经审查过了。因此,为了避免对象 null,我在使用可能为 null 的对象后使用了 try catch 方法。但它仍然抛出可能与 EasyModbus 库本身相关的 System.IO.Port 异常。

答: 暂无答案