You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C#中定时器无法访问device对象,如何快速解决?

问题核心

你遇到的问题本质是作用域限制:device是按钮点击方法内的局部变量,OnTimedEvent方法不在该局部作用域中,因此无法直接访问这个变量;而按钮事件能正常运行,是因为它本身就在device的作用域范围内。

最简单的两种解决方法

方案1:用闭包捕获变量(最简便,无需修改类结构)

直接用Lambda表达式替代独立的OnTimedEvent方法,这样可以直接捕获局部的device变量,无需额外调整类结构:

private void Button_Start_Logging_FMS_Data_Click(object sender, EventArgs e)
{
    try
    {
        var devices = PX409Usbh.DetectDevices().ToList();
        if (devices.Count == 0)
        {
            MessageBox.Show("no devices found. Make sure the pressure sensor is connected");
            return;
        }

        foreach (var d in devices)
        {
            d.Initialize();
        }

        var device = devices[0];
        string serialNumber = device.SerialNumber;
        string unitMeasurement = device.Units;
        double rawExternalPressure = device.ReadPressure();

        // 用Lambda表达式绑定定时器事件,直接捕获device变量
        System.Timers.Timer aTimer = new System.Timers.Timer();
        aTimer.Elapsed += (source, eArgs) => 
        {
            double timedPressure = device.ReadPressure();
            // 这里可添加数据记录、UI更新等后续逻辑
        };
        aTimer.Interval = 1000;
        aTimer.Enabled = true;

    }
    catch (Exception ex)
    {
        Logging.Write_To_Log_File("Error", MethodBase.GetCurrentMethod().Name, "", "", ex.ToString(), "", "", "", 2);
    }
}

方案2:将device提升为类字段(适合多方法复用场景)

如果后续有其他方法需要访问该设备对象,可以把device定义为类的成员变量,打破局部作用域限制:

// 在类的顶部定义成员变量(替换成实际的设备类型)
private PX409Usbh.Device _device;

private void Button_Start_Logging_FMS_Data_Click(object sender, EventArgs e)
{
    try
    {
        var devices = PX409Usbh.DetectDevices().ToList();
        if (devices.Count == 0)
        {
            MessageBox.Show("no devices found. Make sure the pressure sensor is connected");
            return;
        }

        foreach (var d in devices)
        {
            d.Initialize();
        }

        _device = devices[0];
        string serialNumber = _device.SerialNumber;
        string unitMeasurement = _device.Units;
        double rawExternalPressure = _device.ReadPressure();

        System.Timers.Timer aTimer = new System.Timers.Timer();
        aTimer.Elapsed += OnTimedEvent;
        aTimer.Interval = 1000;
        aTimer.Enabled = true;

    }
    catch (Exception ex)
    {
        Logging.Write_To_Log_File("Error", MethodBase.GetCurrentMethod().Name, "", "", ex.ToString(), "", "", "", 2);
    }
}

private void OnTimedEvent(object source, ElapsedEventArgs e)
{
    // 增加空值判断,避免未初始化就调用的异常
    if (_device != null)
    {
        double timedPressure = _device.ReadPressure();
    }
}
注意事项
  • 方案1的闭包会自动维持device的引用,避免对象被GC回收,无需额外处理。
  • 方案2建议始终添加空值判断,防止意外触发定时器时出现空引用异常。

内容的提问来源于stack exchange,提问作者user1438082

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.22 00:54:09