我需要使用特定硬件(气象站)的制造商提供的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();
}
当然,您希望在实例化时设置一些默认值