使用Timer轮询硬件的事件处理

时间:2011-09-22 20:11:48

标签: c# delegates timer event-handling

我需要使用我的特定硬件(气象站)制造商提供的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);

    }
}

1 个答案:

答案 0 :(得分:0)

使用计时器时,您需要启用计时器并确保事件是严格的:

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

供参考:Timers on MSDN

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

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

当然,您需要在实例化时设置一些默认值。