Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Sonstige Fragen zu Delphi (https://www.delphipraxis.net/19-sonstige-fragen-zu-delphi/)
-   -   Delphi Thread blockiert Applikation (anderen Thread) (https://www.delphipraxis.net/86608-thread-blockiert-applikation-anderen-thread.html)

hirnstroem 16. Feb 2007 09:14


Thread blockiert Applikation (anderen Thread)
 
'loha Folks,

in einer Applikation wird ein Thread kreiert. Bei dessen Exekution folgender Code ausgeführt wird:

Delphi-Quellcode:
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;
Kreiert wird der Thread so:

Delphi-Quellcode:
constructor TDBPictureThread.Create(CreateSuspended: boolean; FAddress: String);
begin
  inherited Create(CreateSuspended);
  Self.FAddress := FAddress;
  Self.Execute;
end;
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.

Eintreffende Daten werden ebenfalls über einen Thread verarbeitet (Polling). Dieser Thread sieht momentan folgendermassen aus:

Delphi-Quellcode:
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;
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.

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

ste_ett 16. Feb 2007 10:34

Re: Thread blockiert Applikation (anderen Thread)
 
Versuche mal, den Thread statt mit "Execute()" mit "Resume()" zu starten. :)

hirnstroem 16. Feb 2007 11:10

Re: Thread blockiert Applikation (anderen Thread)
 
Danke ste_ett, sehr nett, Resume hilft in der Tat.

ste_ett 16. Feb 2007 11:22

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. :)

Robert Marquardt 16. Feb 2007 12:40

Re: Thread blockiert Applikation (anderen Thread)
 
Delphi-Quellcode:
constructor TDBPictureThread.Create(CreateSuspended: Boolean; FAddress: string);
begin
  FAddress := FAddress;
  inherited Create(CreateSuspended);
end;
So duerfte es besser sein. FAddress ist dann bereits gesetzt wenn das "inherited Create()" eventuell den Thread gleich ausfuehrt.
Der Aufruf von Execute ist ja falsch und der Aufruf von Resume ist kontraproduktiv. Der Thread wuerde ja starten selbst wenn CreateSuspended True ist.

hirnstroem 16. Feb 2007 12:54

Re: Thread blockiert Applikation (anderen Thread)
 
Mkay, wieder etwas gelernt. Vielen Dank euch beiden!

shmia 16. Feb 2007 13:58

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

sirius 16. Feb 2007 14:06

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...

shmia 16. Feb 2007 14:48

Re: Thread blockiert Applikation (anderen Thread)
 
Zitat:

Zitat von sirius
@shmia Warum kein control in einem Neben-Thread. Im Hauptthread gehts ja auch und solange da keine Interaktion besteht...

Nur der Hauptthread darf direkt mit Controls arbeiten, da die VCL ja nicht threadsicher ist.
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