0

ユーザー定義のクラス内にタイマーがあり、タイマーが起動しないTimer.Enabled.

ユーザー定義クラス:

  TSerialIndicator = public class
  private
    method TxTimerEvent(Sender:System.Object; e:System.EventArgs);
  public    
    Txlight:Label;
    Txtimer:System.Windows.Forms.Timer;
    constructor(mform:Form);
    method Transmit;
    method Receive;
  end;

コンストラクターは次のとおりです。

constructor TSerialIndicator(mform:Form);
begin
    TxLight := new Label;

    TxLight.AutoSize := false;

    TxLight.BorderStyle := BorderStyle.FixedSingle;

    TxLight.Location := new point(52,163);

    TxLight.Width := 20;
    TxLight.Height := 20;

    mform.Controls.Add(TxLight);

    TxTimer := new System.Windows.Forms.Timer;
    TxTimer.Interval:=1;

    TxTimer.Enabled:=false;
    TxTimer.Tick += new System.EventHandler(@TxTimerEvent);

    TxLight.BackColor := Color.Black;
end;

定義されている送信メソッドは次のとおりです。

method TSerialIndicator.Transmit;
begin
  TxLight.BackColor := Color.Red;

  if TxTimer.Enabled = false then
     TxTimer.Enabled:=true;
end;

定義されているTxTimerEventは次のとおりです。

method TSerialIndicator.TxTimerEvent(Sender:System.Object; e:System.EventArgs);
begin
    TxLight.BackColor := Color.Black;
    TxTimer.Enabled:=false;
end;

作成方法と使用方法は次のとおりです。

Slight := new TSerialIndicator(self);
Slight.Transmit;

プログラムの他の部分からTransmitを呼び出すと、それは機能しますが、TxTimerEventはまったく起動しません。Start/Stopのメソッドも試しました。それでもティックイベントは実行されませんでした。ただし、コンストラクター内からタイマーを有効にすると、TxTimerEventが1回起動されることに気付きました。

私は何が間違っているのですか?

前もって感謝します、

4

1 に答える 1

4

「Transmit」や「Receive」などのメソッド名では、スレッドが関係している可能性があります。SerialPortのDataReceivedイベントが実行されるスレッドプールスレッドのように。または、System.Timers.TimerのElapsedイベントが原因で実行されるコード。その他。

System.Windows.Forms.TimerのEnabledプロパティをそのようなワーカースレッドでtrueに設定しても機能せず、スレッドセーフなクラスではありません。通常どおりに実行し、WindowsのSetTimer()メソッドを使用してTickイベントを発生させる非表示のウィンドウを作成します。ただし、そのウィンドウは、メッセージループをポンプしないスレッドで作成されます。したがって、WindowsはWM_TIMERメッセージを生成しません。

必要に応じてControl.Begin/Invoke()を使用して、タイマーまたはコントロールに関連するコードがUIスレッドで実行されるようにします。

于 2012-11-09T16:54:05.777 に答える