事件处理定时器轮询硬件

本文关键字:硬件 定时器 事件处理 | 更新日期: 2023-09-27 18:09:18

我需要使用特定硬件(气象站)的制造商提供的DLL中的函数来请求值。我是c#的新手,委托/事件的概念很难让我理解。尽管如此,我还是设法从DLL中提取了函数,并验证了数据是否通过。我的问题是用计时器定期轮询仪器。在Initialize()中,对象被实例化,但不处理事件,使对象为空。我无计可施,需要一些建议!

public class HardwareData : EventArgs
{
    public float OutsideTemp { get; set; }
    public int OutsideHum { get; set; }
    public float WindSpeed { get; set; }
    public int WindDirection { get; set; }
}
public class Hardware : IDisposable
{
    private static Hardware v;
    private System.Timers.Timer hardwareTimer;
    private int counter = 0;
    private static readonly object padlock = new object();
    public static Hardware Instance
    {
        get
        {
            lock (padlock)
            {
                if (v == null)
                    v = new Hardware();
                return v;
            }
        }
    }
    public void Initialize()
    {
        try
        {
            hardwareTimer = new System.Timers.Timer(500);
            hardwareTimer.Elapsed += new ElapsedEventHandler(hardwareTimer_Elapsed);
            HardwareVue.OpenCommPort_V(3, 19200); //COM port and baud rate are verified.
            hardwareTimer.Start();
        }
        catch (Exception ex)
        {
            throw new InvalidOperationException("Unable to initialize.", ex);
        }
    }
    public HardwareData LastHardware { get; set; }
    void hardwareTimer_Elapsed(object sender, ElapsedEventArgs e)
    {
        try
        {
            counter += 1;
            Console.WriteLine(counter);
            HardwareVue.LoadCurrentHardwareData_V();
            HardwareData v = new HardwareData()
            {
                OutsideTemp = HardwareVue.GetOutsideTemp_V(),
                OutsideHum = HardwareVue.GetOutsideHumidity_V(),
                WindSpeed = HardwareVue.GetWindSpeed_V(),
                WindDirection = HardwareVue.GetWindDir_V()
            };
            LastHardware = v;
        }
        catch (Exception) { }
    }
    public void Dispose()
    {
        HardwareVue.CloseCommPort_V();
        hardwareTimer.Stop();
    }
}

[TestClass]
public class UnitTest1
{
    [TestMethod]
    public void TestMethod1()
    {
        Hardware test = new Hardware();
        try
        {
            if (test != null)
            {
                test.Initialize();
                test.Dispose();
                Assert.AreEqual(0, test.LastHardware.OutsideHum);
            }
        }
        catch (NullReferenceException ex)
        {
            Console.WriteLine("Object is null.");
        }
        // Console.WriteLine(test.LastHardware.OutsideHum);
    }
}

事件处理定时器轮询硬件

当使用计时器时,您需要启用计时器并确保事件被激活:

hardwareTimer.Enabled = true;
hardwareTimer.CanRaiseEvents = true;

参考:MSDN上的定时器

编辑
除了对OP的问题和这个答案的其他评论之外,lasthhardware为空的问题是由于在计时器最初触发之前属性从未被实例化。要解决这个问题,您应该在默认构造函数(或Initialize方法)中实例化lasthhardware属性:

public Hardware()
{
  LastHardware = new HardwareData();
}

当然,您希望在实例化时设置一些默认值