Обработка событий с таймером для опроса оборудования - PullRequest
1 голос
/ 23 сентября 2011

Мне нужно запросить значения с помощью функций в 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 голосов
/ 23 сентября 2011

При работе с таймерами необходимо включить таймер и убедиться, что события сброшены:

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

Для справки: Таймеры на MSDN

Редактировать В дополнение к другим комментариям и к вопросу OP, и к этому ответу, проблема с нулевым значением LastHardware связана с тем, что свойство никогда не создается до первоначального запуска таймера.Чтобы решить эту проблему, вы должны создать экземпляр свойства LastHardware в конструкторе по умолчанию (или в методе Initialize):

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

Конечно, вы хотите установить некоторые значения по умолчанию при создании экземпляра.

...