2

数年前、私のアプリケーションの 1 つで、特定のアプリが特定のシリアル イベントに非常に迅速に応答しなければならなかったときに、シリアル処理をスレッドに移動しました。

それはBDS2006にあり、古いバージョン(3.xくらい?)で、tthread.executeに次のようなコードを入れることで行われました。

    while ...
          begin
          events:=[evRxChar];
          { Prepare a stop event for killing a waiting communication wait. }
           try
             comport1.WaitForEvent(events,stopevent.handle,500);
             if evRxChar in events then
               ComPort1RxChar(comport1,comport1.InputCount); // method of thread.
           on e: exception do {only logs} ;
           end;

初期化は次のようでした

procedure TSerThread.initcomport(comportname:string='COM1');
begin
 comport1:=tcomport.create(nil);
 ComPort1.BaudRate:=br115200;
 ComPort1.DataBits:=dbEight;
 ComPort1.Port:=comportname;

 ComPort1.StopBits:=sbOneStopBit;
 ComPort1.Events:=[];
 ComPort1.Connected:=true;

 StopEvent := TEvent.Create(nil,{ManualReset}false,{InitialState}false,'StopEvent');
end;

rxchar メソッドは、comport1.readstr() を使用して読み取ります

私は最近これを掘り下げる必要があり、tcomport4 を備えた私の Delphi XE では機能しないことに気付きました。ソースを見ると、comport4 が内部スレッド (「オーバーラップ」プロパティ) を処理する方法を変更したというコメントがありましたが、デフォルトは「true」のようで、「クラシック」というコメントがあり、私は

それは古いバージョンとの互換性を意味すると仮定しました。

プロトコルはバイナリであり、すべての string,char<-> ansistring,ansichar の変更は、通常のメインスレッド バージョンで行ったように行われていることに注意してください。

今、本当の質問:

  1. スレッドで tcomport4 を使用している人はいますか?
  2. 上記に明らかな間違いはありますか?
  3. または、別のコンポーネントに移行する必要がありますか?

私はまだ何が起こっているのかをデバッグしていますが、急いでいます.

アップデート

古いターボ Delphi コピーを再インストールし、v3 で動作することを確認しました。コードパスの小さなバグを修正しましたが、思っていたものとは少し異なりました (上記のコードではありません)。

これにより、dxe/comportv4 と bds2006/comportv3 の間の動作をより適切に説明できます。v4 コードは、はるかに多くの読み取りイベント (数百/秒) を生成します。読み取りは、受信キューなどから読み取り文字を削除しないようです。

更新 2

私は最新バージョンで簡単なテストを行い、必要な再配置を行いました (基本的にバイナリ プロトコルの文字列関数の使用を終了します)。アプリケーションが起動時にクラッシュしたため、しばらく動けなくなりましたが、それは私が gnugettext を使用しており、Comport が別の (Unicode ではない?) バージョンをパッケージ化しているためです。しかし、その後は機能します。

残念ながら、この変更を製品バージョン (完全に記述されたプロトコル デコード) に反映するには少しリスクが高いため、中間バージョン (4.0 と 4.11f の間) でテストする必要があります。そのうちにそれを行いますが、どのバージョンが最後の readstr(ansistring) であったかについて何か提案はありますか?

アップデート 3

結局、私は単純に 4.11f ユニットの名前を変更し、それらを古いバージョンと並行して使用し、スレッド コードベースには 4.11f を使用し、既存のコードを維持するために古いバージョンを使用しました。

長期的には、単純に waitforevent コードを使用して独自のバージョンを作成するかもしれません。それに関する主な問題は、待機がタイムアウト、停止イベントなどで終了したかどうかを確認できないことです。これは、たとえば定期的に送信したい場合は、別のタイマーが必要であることを意味します。

4

1 に答える 1

1

こちらで最新の安定版 4.11 リリースにアップグレードする必要があります

于 2011-12-19T20:44:04.373 に答える