如何启动计时器以响应非 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。这将有助于您理解它。

https://msdn.microsoft.com/en-us/library/system.windows.threading.dispatcher.begininvoke%28v=vs.110%29.aspx

//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!
}