数年前、私のアプリケーションの 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 の変更は、通常のメインスレッド バージョンで行ったように行われていることに注意してください。
今、本当の質問:
- スレッドで tcomport4 を使用している人はいますか?
- 上記に明らかな間違いはありますか?
- または、別のコンポーネントに移行する必要がありますか?
私はまだ何が起こっているのかをデバッグしていますが、急いでいます.
アップデート
古いターボ Delphi コピーを再インストールし、v3 で動作することを確認しました。コードパスの小さなバグを修正しましたが、思っていたものとは少し異なりました (上記のコードではありません)。
これにより、dxe/comportv4 と bds2006/comportv3 の間の動作をより適切に説明できます。v4 コードは、はるかに多くの読み取りイベント (数百/秒) を生成します。読み取りは、受信キューなどから読み取り文字を削除しないようです。
更新 2
私は最新バージョンで簡単なテストを行い、必要な再配置を行いました (基本的にバイナリ プロトコルの文字列関数の使用を終了します)。アプリケーションが起動時にクラッシュしたため、しばらく動けなくなりましたが、それは私が gnugettext を使用しており、Comport が別の (Unicode ではない?) バージョンをパッケージ化しているためです。しかし、その後は機能します。
残念ながら、この変更を製品バージョン (完全に記述されたプロトコル デコード) に反映するには少しリスクが高いため、中間バージョン (4.0 と 4.11f の間) でテストする必要があります。そのうちにそれを行いますが、どのバージョンが最後の readstr(ansistring) であったかについて何か提案はありますか?
アップデート 3
結局、私は単純に 4.11f ユニットの名前を変更し、それらを古いバージョンと並行して使用し、スレッド コードベースには 4.11f を使用し、既存のコードを維持するために古いバージョンを使用しました。
長期的には、単純に waitforevent コードを使用して独自のバージョンを作成するかもしれません。それに関する主な問題は、待機がタイムアウト、停止イベントなどで終了したかどうかを確認できないことです。これは、たとえば定期的に送信したい場合は、別のタイマーが必要であることを意味します。