![]() |
Mutithreading: Konsolenausgabe hakt
Hallo,
ich habe ein kleines Delphi7-Programm geschrieben, in welchem ein separater Thread mit Windows.ReadFile() ständig einen seriellen COM-Port scannt und, wenn Daten kommen, diese per Callback (über synchronize)an das Hauptprogramm zurück meldet. Das Hauptprogramm schreibt die Daten dann testweise per writeln() auf ein Konsolenfenster. Das ganze funktioniert, zeigt aber einen merkwürdigen Effekt: Die Konsole schreibt nur Daten, solange ich den Mauszeiger über das Hauptfenster bewege. Was geht da schief? Habe ich was falsch gemacht? |
AW: Mutithreading: Konsolenausgabe hakt
Ohne code - versagt selbst meine Glaskugel momentan...
|
AW: Mutithreading: Konsolenausgabe hakt
|
AW: Mutithreading: Konsolenausgabe hakt
Mein Code ist momentan etwas länglich. Ich versuche den mal auf ein Minimum zu strippen.
Aber ungeachtet dessen: Sind irgendwelche Probleme im Zusammenhang mit Multithreading und der Konsole bekannt? |
AW: Mutithreading: Konsolenausgabe hakt
Mir fehlt auch die Vorstellung wie eine Konsolen-Anwendung etwas über
Delphi-Quellcode:
in den Hauptthread schiebt. Gibt es für eine Delphi Konsolen-Anwendung da überhaupt einen Standardweg?
TThread.Synchronize(..)
|
AW: Mutithreading: Konsolenausgabe hakt
Es ist keine Konsolenanwendung, sondern eine ganz normale Fensteranwendung.
Ich habe dem Linker lediglich gesagt, er soll eine Konsole hinzufügen, zwecks Debugging per Writeln()-Kontrollausgaben. Der Sammlerthread ruft per Synchronize einen TNotify-Event im Hauptthread auf, wenn Daten vorliegen. Wenn ich die Konsole entferne und statt dessen die Daten in eine Listbox schreibe, funktioniert komischerweise alles ganz normal. Gibts dafür irgendeine Erklärung? |
AW: Mutithreading: Konsolenausgabe hakt
Zitat:
Mein Consolenlogger macht es so:
Delphi-Quellcode:
FOutputHandle := GetStdHandle( STD_OUTPUT_HANDLE );
Btw: Auch im Thread... |
AW: Mutithreading: Konsolenausgabe hakt
Ok, hier der Minimalcode, der das Problem zeigt:
Delphi-Quellcode:
Das ist eine ganz normale Delphi7-Fensteranwendung mit einem Fenster (Form1, leer), wobei bei den Linkeroptionen "Generate Console Application" angeklickt sein muss.
unit Unit1;
interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs; type TPoll = class(TThread) private { Private declarations } POnData : TNotifyEvent; protected constructor Create(OnData: TNotifyevent); procedure Notify; procedure Execute; override; end; type TForm1 = class(TForm) procedure FormCreate(Sender: TObject); procedure FormClose(Sender: TObject; var Action: TCloseAction); private { Private declarations } i: integer; P: TPoll; procedure PData(Sender: TObject); public { Public declarations } end; var Form1: TForm1; implementation {$R *.dfm} constructor TPoll.Create(OnData: TNotifyevent); begin inherited Create(true); Suspended:=false; FreeOnTerminate:=true; POnData:=OnData; end; procedure TPoll.Notify; begin if assigned(POnData) then POnData(nil); end; procedure TPoll.Execute; begin repeat sleep(500); Synchronize(Notify); until terminated; end; procedure TForm1.PData(Sender: TObject); begin inc(i); writeln('data packet ',i); end; procedure TForm1.FormCreate(Sender: TObject); begin i:=0; P:=TPoll.Create(PData); end; procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction); begin P.Terminate; end; end. Nach meinem Verständniss müsste alle 0,5s eine Zeile auf die Konsole ausgegeben werden. Solange die Maus sich nicht bewegt, bleibt der Thread allerdings unerklärlicherweise stehen und es kommt nix. Hoffentlich ist die Kristallkugel jetzt überflüssig... |
AW: Mutithreading: Konsolenausgabe hakt
Moin...:P
Warum verpaßt du dem Thread nicht ein Event mit den "Arbeitsdaten". :gruebel: ...ungetestet:
Delphi-Quellcode:
unit Unit1;
interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs; type TWorkEvent = procedure(Sender: TObject; WorkStep: Integer); TPoll = class(TThread) private FStep: Integer; FOnWork: TWorkEvent; procedure SyncWork; protected constructor Create; property OnWork: TOnWorkEvent read FOnWork write FOnWork; procedure Execute; override; end; type TForm1 = class(TForm) procedure FormCreate(Sender: TObject); procedure FormClose(Sender: TObject; var Action: TCloseAction); private FPoll: TPoll; procedure DoOnWork(Sender: TObject; WorkStep: Integer); public { Public declarations } end; var Form1: TForm1; implementation {$R *.dfm} constructor TPoll.Create; begin inherited Create(True); Suspended := False; FreeOnTerminate := True; FStep := 0; end; procedure TPoll.Execute; begin repeat sleep(500); Synchronize(SyncWork); // weitere Steps until terminated; end; procedure TPoll.SyncWork; begin if Assigned(FOnWork) then begin FOnWork(Self, FStep); end; end; procedure TForm1.FormCreate(Sender: TObject); begin FPoll := TPoll.Create; FPoll.OnWork := DoOnWork; end; procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction); begin FPoll.Free; end; procedure TForm1.DoOnWork(Sender: TObject; WorkStep: Integer); begin writeln('data packet ', WorkStep); end; end. |
AW: Mutithreading: Konsolenausgabe hakt
OK - Du gibst also nicht in ein Consolenfenster aus sondern es IST ein consolen Application?!?
Wofür dann das Form? Hat ein Consolenprogramm überhaupt einen UI-Thread? |
Alle Zeitangaben in WEZ +1. Es ist jetzt 13:45 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