![]() |
Thread blockiert Applikation (anderen Thread)
'loha Folks,
in einer Applikation wird ein Thread kreiert. Bei dessen Exekution folgender Code ausgeführt wird:
Delphi-Quellcode:
Kreiert wird der Thread so:
procedure TDBPictureThread.Execute;
var imgReceived: TIWImage; Address, UserID, Command: String; begin imgReceived := TIWImage.Create(nil); PictureDeviceAddress := HexStrToInt(FAddress); UserID := CANBus.GetUserID; Address := IntToHex(HexStrToInt(FAddress) or (StrToInt(UserID) shl 21), 2); Command := '1E'; CANBus.SendMessage (Address, '8', Command, '0', '0', '0', '0', '0', '0'); // hier wird ein Bild angefordert imgReceived.Picture.Bitmap := CANCommunication.TryToGetPicture(FAddress, UserID, Command); // hier wird nachgeschaut ob das Bild schon da ist und so imgReceived.Picture.SaveToFile('C:\Dokumente und Einstellungen\ava\Desktop\' + DateTimeToStr(Now) + '.bmp'); // UCommunication.DBPictureBuffer.Data.Clear; DBPictureFlag := True; Self.Terminate; end;
Delphi-Quellcode:
Das eigentliche Problem ist nun, dass nach dem versenden einer CAN-Message, die ankommenden Daten erst dann verarbeitet werden, wenn der Thread terminiert wurde und das will ich nicht.
constructor TDBPictureThread.Create(CreateSuspended: boolean; FAddress: String);
begin inherited Create(CreateSuspended); Self.FAddress := FAddress; Self.Execute; end; Eintreffende Daten werden ebenfalls über einen Thread verarbeitet (Polling). Dieser Thread sieht momentan folgendermassen aus:
Delphi-Quellcode:
Mir ist bewusst, dass dieser Thread die CPU unnötig belastet, aber aufgrund zur Zeit noch fehlernder Callback-Funktionen des Treibers, mache ich das ganze vorübergehend auf diese Weise.
procedure TRxThread.Execute;
var InputString: String; i: Integer; CANMessage: CANMsg; begin repeat if (CANUSBRead(CANMessage) = ERROR_CANUSB_OK) then begin InputString := '0' + IntToHex(CANMessage.id, 2) + IntToHex(CANMessage.len, 2); for i := 0 to CANMessage.len do InputString := InputString + IntToHex(CANMessage.data[i], 2); CANCommunication.WriteDataIntoBuffer(InputString); end; until 1 <> 1; end; Wie gesagt, der TRxThread beginnt erst dann mit seiner arbeit, wenn der TDBPictureThread terminiert wird. Ist das normal so? Oder gibt es eine Möglichkeit, dass dieser TRxThread auch dann weiterarbeitet, wenn der TDBPictureThread am laufen ist? Grüsse hirsntroem |
Re: Thread blockiert Applikation (anderen Thread)
Versuche mal, den Thread statt mit "Execute()" mit "Resume()" zu starten. :)
|
Re: Thread blockiert Applikation (anderen Thread)
Danke ste_ett, sehr nett, Resume hilft in der Tat.
|
Re: Thread blockiert Applikation (anderen Thread)
"Resume()" bedeutet, dass die Methode wirklich in einem extra Thread ausgeführt wird.
Wenn man "Execute()" direkt aufruft, wird die Methode in selben Thread ausgeführt. :) |
Re: Thread blockiert Applikation (anderen Thread)
Delphi-Quellcode:
So duerfte es besser sein. FAddress ist dann bereits gesetzt wenn das "inherited Create()" eventuell den Thread gleich ausfuehrt.
constructor TDBPictureThread.Create(CreateSuspended: Boolean; FAddress: string);
begin FAddress := FAddress; inherited Create(CreateSuspended); end; Der Aufruf von Execute ist ja falsch und der Aufruf von Resume ist kontraproduktiv. Der Thread wuerde ja starten selbst wenn CreateSuspended True ist. |
Re: Thread blockiert Applikation (anderen Thread)
Mkay, wieder etwas gelernt. Vielen Dank euch beiden!
|
Re: Thread blockiert Applikation (anderen Thread)
Ich sehe da noch :shock: üble Dinge :shock: in deinem Code.
1.) Warum benützt du TIWImage ? TImage und alles was davon abgeleitet wurde ist doch ein Control und Controls haben in einem Thread nichts zu suchen ==> TPicture verwenden 2.) Speicherleck: imgReceived.Free fehlt 3.) kein Resourcen-Schutzblock vorhanden |
Re: Thread blockiert Applikation (anderen Thread)
Warum self.terminate am Ende? Das macht doch der Thread an dieser Stelle sowieso.
@shmia Warum kein control in einem Neben-Thread. Im Hauptthread gehts ja auch und solange da keine Interaktion besteht... |
Re: Thread blockiert Applikation (anderen Thread)
Zitat:
Neben-Threads müssen sich über .Synchronize() beim Hauptthread melden und im Kontext vom Hauptthread dürfen dann Manipulationen von Controls stattfinden. Da das Image im Beispiel keinen Parent zugewiesen bekommen hat, passiert so auch nichts. Aber es ist einfach unsauber und unnötig. |
Alle Zeitangaben in WEZ +1. Es ist jetzt 08:52 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz