C# 使用计时器轮询硬件的事件处理
我需要使用特定硬件(气象站)制造商提供的DLL中的函数来请求值。我是C#的新手,代表/事件的概念很难让我理解。尽管如此,我还是设法从DLL中提取了函数,并验证了数据是否能够通过。我的问题是使用计时器定期轮询仪器。在C# 使用计时器轮询硬件的事件处理,c#,delegates,timer,event-handling,C#,Delegates,Timer,Event Handling,我需要使用特定硬件(气象站)制造商提供的DLL中的函数来请求值。我是C#的新手,代表/事件的概念很难让我理解。尽管如此,我还是设法从DLL中提取了函数,并验证了数据是否能够通过。我的问题是使用计时器定期轮询仪器。在Initialize()中,实例化了一个对象,但不处理该事件,将对象保留为null。我没有主意了,想听听你的建议 public class HardwareData : EventArgs { public float OutsideTemp { get; set; }
Initialize()
中,实例化了一个对象,但不处理该事件,将对象保留为null。我没有主意了,想听听你的建议
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;
供参考:
编辑除了对OP的问题和此答案的其他注释外,LastHardware为null的问题是由于在计时器最初启动之前从未实例化该属性。要解决此问题,您应该在默认构造函数(或
Initialize
方法)中实例化LastHardware属性:
当然,您希望在实例化时设置一些默认值。初始化测试,然后立即处理它(终止计时器)。True。在我看来,计时器将经过一个间隔,加载数据,然后被处理。不,你需要暂停线程以等待计时器启动。尝试在初始化和处置之间添加类似Thread.Sleep(2000)的内容。我的意思是只为测试而这样做,在实际的应用程序中,只需继续您的业务并做其他事情。或者,您可以将硬件类之外的计时器带到测试类中,并在test.PollHardware()调用后,在TimeRecursed处理程序的末尾调用dispose方法,或者您想调用的任何方法。您只需将“test”作为计时器访问它的全局引用即可。啊哈!非常感谢。我现在可以测试并查看正在传输的数据,并且默认情况下timer incrementing.CanRaiseEvents为true,timer.Start()与timer.Enabled=true相同。我想说,真正的问题是,正如Alex指出的,他在初始化后立即处理,因此没有足够的时间来做任何事情。这就是我的绝对困惑:在测试类中,如果我要声明一个计数器,用于每间隔递增,我不知道在循环中包装什么,这样我就可以测试多个计时器间隔。for(int I=0;I<5;I++){timer mytimer=new timer(100*I);mytimer.appeased+=new ElapsedEventHandler(mytimer_appeased);}void mytimer_appeased(对象发送方,ElapsedEventArgs e){int I=((timer)发送方).Interval/100;Console.WriteLine(“计时器编号”+i.toString()+“已用”);}
public Hardware()
{
LastHardware = new HardwareData();
}