如何启动计时器以响应非 UI 事件(例如串行端口 activity)?
How do I start up a timer in reaction to a non-UI event (such as serial port activity)?
计时器 (System.Windows.Forms
) 从主 UI 启动时(例如通过按钮)确实启动正常。但是,当信号来自另一个地方时,我无法完全启动它——在本例中,来自串行端口的事件。
我知道这里需要某种方式 BeginInvoke
/Invoke
和委托,但是,作为一名新程序员,我不明白,我需要一些帮助。
//button in the main UI. Fires up the timer.
private void button1_Click(object sender, EventArgs e)
{
timer1.Enabled = true; //this one here works perfectly
}
//an event handler for a serial port event, does NOT fire up the timer.
public void SomethingHappenedWithTheSerialPort(object sender, EventArgs eventrgs)
{
timer1.Enabled = true; //does NOT work at all. I don't know how to use Invoke.
}
编辑:这就是我打开端口并监听 PinChanged 事件的方式。
int baudrate = 9600;
int databits = 8;
Main mainhandler = new Main();
System.IO.Ports.SerialPort ComPorttoUse = new SerialPort(Properties.Settings.Default.COMPortToUse, baudrate, Parity.None, databits, StopBits.One);
ComPorttoUse.Handshake = Handshake.None;
ComPorttoUse.PinChanged += new SerialPinChangedEventHandler(mainhandler.PortDetectWhatPinChanged);
ComPorttoUse.Open();
试试下面的代码。
Application.Current.Dispatcher.BeginInvoke((Action)(() =>{timer1.Enabled = true;}));
阅读有关调度程序的 MSDN。这将有助于您理解它。
//an event handler for a serial port event, does NOT fire up the timer.
public void SomethingHappenedWithTheSerialPort(object sender, EventArgs eventrgs)
{
timer1.Enabled = true; //does NOT work at all. I don't know how to use Invoke.
}
此事件处理程序从未被调用,因为您似乎尚未为其订阅 SerialPort
对象的任何事件。相反,您已将名为 PortDetectWhatPinChanged
的处理程序方法订阅到 PinChanged
事件:
ComPorttoUse.PinChanged += new SerialPinChangedEventHandler(mainhandler.PortDetectWhatPinChanged);
如果您希望 SomethingHappenedWithTheSerialPort
被调用,您需要 "add" 它到事件中:
ComPorttoUse.PinChanged += new SerialPinChangedEventHandler(SomethingHappenedWithTheSerialPort);
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^
// note: not required, the compiler can usually infer this bit.
并且您的处理程序方法必须具有与 PinChanged
事件兼容的签名,因此您需要将其更改为:
public void SomethingHappenedWithTheSerialPort(object sender, SerialPinChangedEventArgs e)
{ // ^^^^^^^^^^^^^^^^^^^^^^^^^
timer1.Enabled = true; // this needs changing!
}
计时器 (System.Windows.Forms
) 从主 UI 启动时(例如通过按钮)确实启动正常。但是,当信号来自另一个地方时,我无法完全启动它——在本例中,来自串行端口的事件。
我知道这里需要某种方式 BeginInvoke
/Invoke
和委托,但是,作为一名新程序员,我不明白,我需要一些帮助。
//button in the main UI. Fires up the timer.
private void button1_Click(object sender, EventArgs e)
{
timer1.Enabled = true; //this one here works perfectly
}
//an event handler for a serial port event, does NOT fire up the timer.
public void SomethingHappenedWithTheSerialPort(object sender, EventArgs eventrgs)
{
timer1.Enabled = true; //does NOT work at all. I don't know how to use Invoke.
}
编辑:这就是我打开端口并监听 PinChanged 事件的方式。
int baudrate = 9600;
int databits = 8;
Main mainhandler = new Main();
System.IO.Ports.SerialPort ComPorttoUse = new SerialPort(Properties.Settings.Default.COMPortToUse, baudrate, Parity.None, databits, StopBits.One);
ComPorttoUse.Handshake = Handshake.None;
ComPorttoUse.PinChanged += new SerialPinChangedEventHandler(mainhandler.PortDetectWhatPinChanged);
ComPorttoUse.Open();
试试下面的代码。
Application.Current.Dispatcher.BeginInvoke((Action)(() =>{timer1.Enabled = true;}));
阅读有关调度程序的 MSDN。这将有助于您理解它。
//an event handler for a serial port event, does NOT fire up the timer. public void SomethingHappenedWithTheSerialPort(object sender, EventArgs eventrgs) { timer1.Enabled = true; //does NOT work at all. I don't know how to use Invoke. }
此事件处理程序从未被调用,因为您似乎尚未为其订阅 SerialPort
对象的任何事件。相反,您已将名为 PortDetectWhatPinChanged
的处理程序方法订阅到 PinChanged
事件:
ComPorttoUse.PinChanged += new SerialPinChangedEventHandler(mainhandler.PortDetectWhatPinChanged);
如果您希望 SomethingHappenedWithTheSerialPort
被调用,您需要 "add" 它到事件中:
ComPorttoUse.PinChanged += new SerialPinChangedEventHandler(SomethingHappenedWithTheSerialPort);
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^
// note: not required, the compiler can usually infer this bit.
并且您的处理程序方法必须具有与 PinChanged
事件兼容的签名,因此您需要将其更改为:
public void SomethingHappenedWithTheSerialPort(object sender, SerialPinChangedEventArgs e)
{ // ^^^^^^^^^^^^^^^^^^^^^^^^^
timer1.Enabled = true; // this needs changing!
}