Delphi-PRAXiS
Seite 1 von 3  1 23      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Sonstige Fragen zu Delphi (https://www.delphipraxis.net/19-sonstige-fragen-zu-delphi/)
-   -   Delphi Mutithreading: Konsolenausgabe hakt (https://www.delphipraxis.net/192279-mutithreading-konsolenausgabe-hakt.html)

iphi 5. Apr 2017 09:42

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?

Mavarik 5. Apr 2017 09:46

AW: Mutithreading: Konsolenausgabe hakt
 
Ohne code - versagt selbst meine Glaskugel momentan...

himitsu 5. Apr 2017 09:55

AW: Mutithreading: Konsolenausgabe hakt
 
MSDN-Library durchsuchenSetCursorPos in einem schnellen Timer.

Nun aber mal Ernst ... siehe Mavarik.

iphi 5. Apr 2017 10:01

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?

Der schöne Günther 5. Apr 2017 10:01

AW: Mutithreading: Konsolenausgabe hakt
 
Mir fehlt auch die Vorstellung wie eine Konsolen-Anwendung etwas über
Delphi-Quellcode:
TThread.Synchronize(..)
in den Hauptthread schiebt. Gibt es für eine Delphi Konsolen-Anwendung da überhaupt einen Standardweg?

iphi 5. Apr 2017 10:12

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?

Mavarik 5. Apr 2017 10:16

AW: Mutithreading: Konsolenausgabe hakt
 
Zitat:

Zitat von Der schöne Günther (Beitrag 1366483)
Mir fehlt auch die Vorstellung wie eine Konsolen-Anwendung etwas über
Delphi-Quellcode:
TThread.Synchronize(..)
in den Hauptthread schiebt. Gibt es für eine Delphi Konsolen-Anwendung da überhaupt einen Standardweg?

hmm...

Mein Consolenlogger macht es so:

Delphi-Quellcode:
      FOutputHandle := GetStdHandle( STD_OUTPUT_HANDLE );

Btw: Auch im Thread...

iphi 5. Apr 2017 11:06

AW: Mutithreading: Konsolenausgabe hakt
 
Ok, hier der Minimalcode, der das Problem zeigt:

Delphi-Quellcode:
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.
Das ist eine ganz normale Delphi7-Fensteranwendung mit einem Fenster (Form1, leer), wobei bei den Linkeroptionen "Generate Console Application" angeklickt sein muss.
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...

haentschman 5. Apr 2017 11:28

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.

Mavarik 5. Apr 2017 11:29

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 00:14 Uhr.
Seite 1 von 3  1 23      

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz