Also wie schon oben gesagt, das pollen im Execute ist sicher nicht die feine englische Art. Mit
WaitCommEvent und einer Overlapped-Struktur bereitest du die Comm-Events vor. Über eigene Events kannst Du dir das Öffnen/Schließen und Beenden deines Threads realisieren. Mit
WaitForMultipleObjects wartest du dann:
Delphi-Quellcode:
procedure TCommThread.Execute;
var
Handles: Array[0..3] Of THandle;
dummy: DWord;
begin
Handles[0] := hTerminateEvent;
Handles[1] := iOverlapped.hEvent;
Handles[2] := hClosePortEvent;
Handles[3] := hOpenPortEvent;
repeat
WaitCommEvent(FCommHandle, FEvtMask, @iOverlapped); // Init Wait (returnes immediately, because of overlapped event)
Case WaitForMultipleObjects(4, @Handles, FALSE, INFINITE) Of // Wait for an event to occur
WAIT_OBJECT_0+0: Begin
Terminate;
Break;
End;
// Zeichen empfangen
WAIT_OBJECT_0+1: Begin
If GetOverlappedResult(FCommHandle, iOverlapped, dummy, FALSE) Then Begin
If ClearCommError(FCommHandle, fErrorMask, @fCT) Then Begin
If (fEvtMask=EV_RXCHAR) And (fCT.cbInQue=0) Then Continue; // restart loop!!
If Assigned(FOnThreadEvent) Then Synchronize(DoOnThreadEvent);
End
Else GetLastError; // returns 6 (INVALID_HANDLE)
End
Else Begin
dummy := GetLastError; // reset error
ResetEvent(iOverlapped.hEvent); // new 30.6.2003 (reset false event)
End;
End;
// Schnittstelle schließen
WAIT_OBJECT_0+2:
Begin
CloseHandle(fCommHandle);
fCommHandle := INVALID_HANDLE_VALUE;
ResetEvent(hClosePortEvent);
End;
// Schnittstelle öffnen
WAIT_OBJECT_0+3:
Begin
InitializePort;
ResetEvent(hOpenPortEvent);
End;
else Begin
// Should never happen (DON'T EXIT)
End;
End;
until Terminated;
CloseHandle(FCommHandle);
fCommHandle := INVALID_HANDLE_VALUE;
CloseHandle(iOverlapped.hEvent);
CloseHandle(hTerminateEvent);
CloseHandle(hClosePortEvent);
CloseHandle(hOpenPortEvent);
end;
Das ist ein Auszug aus meiner eigenen Komponente, das Schreiben besorgt ein eigener WriteThread - für alle Comms gemeinsam.