Autor Beitrag
Omid
Hält's aus hier
Beiträge: 14



BeitragVerfasst: Di 06.04.10 20:09 
Hallo,
Ich versuche ein Programm in Delphi zu schreiben ( Anfänger). Ich will Daten von einer Anlage lesen und die bearbeiten. Die Daten sollen ständig gelesen und weiter verarbeitet werde. Wenn ich aber eine Form aufrufe, passier aber erst, wenn ich ein Button anklicke. Das hilft mir aber nicht. Meine Procedure soll bis auf beenden der Form weiter laufen. Wie kann ich das realisieren? Ich bedanke mich für jeder nützliche Hinweis.
platzwart
ontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic starofftopic star
Beiträge: 1054
Erhaltene Danke: 78

Win 7, Ubuntu 9.10
Delphi 2007 Pro, C++, Qt
BeitragVerfasst: Di 06.04.10 20:16 
Du könntest im OnCreate der Form (also beim erstellen der Form) einen Thread starten, der dann die Verarbeitung übernimmt.

_________________
Wissenschaft schafft Wissenschaft, denn Wissenschaft ist Wissenschaft, die mit Wissen und Schaffen Wissen schafft. (myself)
Narses
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Administrator
Beiträge: 10183
Erhaltene Danke: 1256

W10ent
TP3 .. D7pro .. D10.2CE
BeitragVerfasst: Di 06.04.10 20:23 
Moin und :welcome: im Forum!

Da du noch Anfänger bist, versuch doch mal mit der Suche in: Delphi-Forum, Delphi-Library TTIMER-Komponente regelmäßig eine Aktion auszuführen. :idea: Der Ansatz mit dem Thread ist sicher gut, aber sicher erst für Fortgeschrittene sinnvoll einsetzbar. ;)

cu
Narses

_________________
There are 10 types of people - those who understand binary and those who don´t.
Omid Threadstarter
Hält's aus hier
Beiträge: 14



BeitragVerfasst: Mi 07.04.10 20:07 
Guten Abend,
Danke für die schnelle Antwort. Mit dem Thread kann ich noch nicht anfangen. Die Lösung mit Timer dachte ich ,wäre einfacher. zu Früh gefreut. Meine Programm hat nur Form1 und Form2. Der Form1 ist die Maske und in dem Form2 habe ich ein Timer.
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
Var
 Form2:Tform2
Implementation
{$R*.dfm}
Procedure Eingang;
Begin
// hier werden die Daten von Anlage geholt
End;

procedure Tform2.Timer1Timer(Sender:tobject);
Begin
Eingang;
End;
End.

Sobald ich den Form2 aus Form1 aufrufe kommt eine Fehlermeldung:
Ein Execption der Klasse EaccessViolation aufgetreten.........
Wenn ich die Eingabe von Timer procedure wegnehme ist okay, aber keine Ergebnisse.
Wo ist Bitte meine Fehler?

Moderiert von user profile iconNarses: Delphi-Tags hinzugefügt
Xion
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
EE-Maler
Beiträge: 1952
Erhaltene Danke: 128

Windows XP
Delphi (2005, SmartInspect), SQL, Lua, Java (Eclipse), C++ (Visual Studio 2010, Qt Creator), Python (Blender), Prolog (SWIProlog), Haskell (ghci)
BeitragVerfasst: Mi 07.04.10 20:20 
user profile iconOmid hat folgendes geschrieben Zum zitierten Posting springen:

Wenn ich die Eingabe von Timer procedure wegnehme ist okay, aber keine Ergebnisse.
Wo ist Bitte meine Fehler?

Ich würde sagen der Fehler ist in der procedure Eingabe...besonders wenns eine AccessViolation ist.

_________________
a broken heart is like a broken window - it'll never heal
In einem gut regierten Land ist Armut eine Schande, in einem schlecht regierten Reichtum. (Konfuzius)
Omid Threadstarter
Hält's aus hier
Beiträge: 14



BeitragVerfasst: Do 08.04.10 13:24 
Hallo
Vielen Dank für eure Hinweise. Das hat mir gut geholfen. Das Problem ist gelöst. Es gibt aber ein Phänomen, die sehr störend auf mein Programm wirkt. Sobald ich die Procedere Eingabe in der Timer Procedere aufrufe, wird das Programm sehr träge. Die Reaktion auf meine Befehle ist mit Verzögerung. Ich habe die Intervallzeit von Timer geändert, hat aber kein Einfluss. Diese Verzögerung wirkt auf gesamtes Programm, nicht nur der Form2, wo der Timer aufgerufen wird.
Ist das normal?
Tropby
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 71
Erhaltene Danke: 4

Vista, Win XP, Win 89
Turbo Delphi Ex.
BeitragVerfasst: Do 08.04.10 13:39 
Wenn deine Procedure die von dem Timer aufgerufen wird etwas Zeit in anspruch nimmt dann ist das vollkommen normal. Da beide Formulare im gleichem Thread liegen wirst du da auch nicht viel machen können....

Du könntest probieren, zwischendurch in deiner Procedure mal Application.ProcessMessages aufzurufen um die anderen Programmteile ausführen zu lassen.

_________________
Tropby
Omid Threadstarter
Hält's aus hier
Beiträge: 14



BeitragVerfasst: Do 08.04.10 19:44 
Hi
ich habe ( Application.ProcessMessages) verwendet, hat nicht viel gebraucht. Meine Procedure Eingabe wird noch rechenaufwendiger. das bedutet mein Programm wird zu lagsam.
wenn es keine andere moeglichkeiten gibt, muss ich wohl mit Thread arbeiten. Ich arbeite sei paar tagen mit Delphi. Hat jemand eine Quelle fuer anfaenger, wo einfach erklaert ist, oder eine Einfache Beispiel mit thread.

Omid :les:
MaPsTaR
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 90
Erhaltene Danke: 4

Win XP
Delphi 7 Enterprise
BeitragVerfasst: Sa 10.04.10 10:49 
Wie bereits von user profile iconXion erwähnt, wird der Fehler wohl in Eingabe liegen.
Allerdings wird dir, ohne den Code dieser Prozedur, niemand groß weiterhelfen können.

user profile iconOmid hat folgendes geschrieben Zum zitierten Posting springen:

ausblenden Delphi-Quelltext
1:
2:
3:
4:
Procedure Eingang;
Begin
// hier werden die Daten von Anlage geholt
End;

...lässt eher wenig Möglichkeiten den Fehler zu finden.

_________________
Liebe Kinder, es stimmt ... solnage auch nur der ertse und lezte Bchutsabe rihctig ist und alle andreen Bcuhsatben irgendwie vorahnden sind,
dann knan man es dennonch lesen, also macht nur weiter so, wir verstehen euch schon
Omid Threadstarter
Hält's aus hier
Beiträge: 14



BeitragVerfasst: Sa 10.04.10 17:23 
Hallo
Mein Programm funktioniert ohne Probleme. Ich kann auch die Daten von der Anlage lesen.
Ich verwende ein Timer. Durch die Timer entstehende Zeitverzögerung ist zu groß. Ich muss meine Daten je 500ms lesen .“ ich habe ( Application.ProcessMessages) verwendet, hat aber nicht viel gebraucht.“.
Hier meine die Zeitverzögerung hat sich nicht geändert. Mein Problem ist also die Verzögerung durch die Timer.
Platzwart schlägt Verwendung von einem Thread. Ich habe über Threads etwas gelesen. Ob ein Thread mein Problem löst( die Zeit Verzögerung)?
Wenn ich meine Prozedur Eingabe in eine schleife aufrufen könnte, wäre ideal.
Das klappt aber nicht. In der Eingabe greife ich auf die serielle Schneistelle (Com 1) der Rechner. Ohne Verwendung von Schleife funktioniert mein Programm richtig. Sobald ich die Eingabe in einem schleife aufrufen reagiere das Programm nicht mehr. Kann man mit Delphi in einer Buttonklick Procedere ( Online) eine Schleife einbauen, und mit einer weiteren Buttonklick Procedere ( Offline) die schleifen beenden?
Tropby
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 71
Erhaltene Danke: 4

Vista, Win XP, Win 89
Turbo Delphi Ex.
BeitragVerfasst: Sa 10.04.10 17:36 
Das würde ich dann über einen Thread machen. Der eine Button startet den Thread mit der Schleife in ihm und der zweite Button Beendet oder Pausiert den Thread.

Da es bei Delphi das Objekt TThread gibt ist das auch nicht gerade schwer zu machen. Ein Beispiel hab ich jedoch gerade nicht zur Hand....

_________________
Tropby
Omid Threadstarter
Hält's aus hier
Beiträge: 14



BeitragVerfasst: So 11.04.10 05:02 
Hi Tropby,
ich brauche genau das,was du beschrieben hast.

( Das würde ich dann über einen Thread machen. Der eine Button startet den Thread mit der Schleife in ihm und der zweite Button Beendet oder Pausiert den Thread.)

ich vesuche es mit Thread.muss ich aber erst lernen wie man so ein Thread difiniert und einsetzt. eine einfache Beispiel waere prima.

Vielen Dank
Tropby
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 71
Erhaltene Danke: 4

Vista, Win XP, Win 89
Turbo Delphi Ex.
BeitragVerfasst: So 11.04.10 10:37 
Hier ist ein kurzes Tutorial: www.delphi-treff.de/...scal/threads/page/7/

Da ist nur nicht so alles zu dem TThread erklährt.
Allgemein würde ich sagen:

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
uses
  classes;

type
  TMyThread = class(TThread)
    private
      { Private-Deklarationen }
    protected
      procedure Execute; override;
    end;

......


procedure TMyThread.Execute;
begin
  while not Self.Terminated do
  begin
    DoSomething();
    
  end;
end;


Und das zum starten:

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
  MyThread : TMyThread;

  ...

  MyThread := TMyThread.create(true / false);
  MyThread.Resume;


Das ist alles nicht getestet... Sollte aber so oder so ähnlich funktionieren.

_________________
Tropby
Xion
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
EE-Maler
Beiträge: 1952
Erhaltene Danke: 128

Windows XP
Delphi (2005, SmartInspect), SQL, Lua, Java (Eclipse), C++ (Visual Studio 2010, Qt Creator), Python (Blender), Prolog (SWIProlog), Haskell (ghci)
BeitragVerfasst: So 11.04.10 13:33 
user profile iconOmid hat folgendes geschrieben Zum zitierten Posting springen:

Ich verwende ein Timer. Durch die Timer entstehende Zeitverzögerung ist zu groß. Ich muss meine Daten je 500ms lesen .“ ich habe ( Application.ProcessMessages) verwendet, hat aber nicht viel gebraucht.“.
Hier meine die Zeitverzögerung hat sich nicht geändert. Mein Problem ist also die Verzögerung durch die Timer.

Mal ne dumme Frage. Ist es nicht möglich, dass die Übertragung einfach nur länger als 500ms dauert? dann kannst du machen was du willst, du wirst es nicht schneller hinbekommen, da der COM-Port nicht sonderlich schnell ist.

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
//Timer
var t: cardinal;
begin
  t:=GetTickCount;
  Eingabe;
  Form1.Caption:=inttostr(GetTickCount-t);
end;

Das zeigt dir an wieviele ms deine procedure Eingabe braucht. Ist das mehr als 500ms, dann kannst du auch mit threads nix erreichen. Vielleicht wäre es auch besser, den Timer abzustellen
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
//Timer
var t: cardinal;
begin
  Timer.Enabled:=False;
  t:=GetTickCount;
  Eingabe;
  Form1.Caption:=inttostr(GetTickCount-t);
  Timer.Enabled:=True;
end;

damit du nicht mehrmals "gleichzeitig" die procedure aufrufst, wenn die procedure mehr als 500ms braucht.

_________________
a broken heart is like a broken window - it'll never heal
In einem gut regierten Land ist Armut eine Schande, in einem schlecht regierten Reichtum. (Konfuzius)
Omid Threadstarter
Hält's aus hier
Beiträge: 14



BeitragVerfasst: So 11.04.10 19:55 
Hallo und danke für die Information.

Also, etwas über meine Prozedur Eingabe: Ich lese / schreibe die Daten aus /in eine S7 über MPI Schnittstelle ( Simatic Prodave). Der Zykluszeit meine SPS Programm ist 500ms. Es muss aber nicht jeder Zyklus gelesen werden . Je 4. Zyklus wurde auch reichen.

@ Xion

Ich habe die Zeitmessung wie du geschrieben hast, durchgeführt. Meine Prozedur Eingabe braucht 5949 ms. Wenn ich die Timer abstellen ändert sich die zeit nicht viel (ca. 15 ms).

@Tropby

Mit deine Information habe ich meine alle erste Thread versuche gestartet. Die Zeit wird nicht viel kleiner aber mein Programm ist nicht mehr träger. Es funktioniert.Immer hin gut.
Hier ist die Delphi Quelltext:

ausblenden volle Höhe Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:
80:
81:
82:
83:
84:
unit Unit2;
interface
uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, ExtCtrls,prodave;
type
  TMYThread=class(TThread)
      protected
      procedure Execute; Override;
      end;
  TForm2 = class(TForm)
    ende: TButton;
    Timer1: TTimer;
    Edit1: TEdit;
    Edit2: TEdit;
    Online: TButton;
    Offline: TButton;
    procedure endeClick(Sender: TObject);
    procedure Timer1Timer(Sender: TObject);
    procedure OnlineClick(Sender: TObject);
    procedure OfflineClick(Sender: TObject);
  private
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
  end;
var
  Form2: TForm2;
implementation
{$R *.dfm}
uses pvar;
procedure Eingabe;
Var
Abbyte,Anzahl:integer;
Begin
 // Werte Holen
     Abbyte:=124;
     Anzahl:=1;
     Res_R:= load_tool(1, addr(sps_name),addr(sps_adr_table[0]));
      if Res_R=0 then
      E_field_read(Abbyte,Anzahl,RW_byte);
      Res_R:=Unload_Tool;
end;
//--------------------------------Werte holen
procedure Tmythread.Execute;
Begin
while not self.terminated do
begin
 Eingabe;
 Form2.Edit2.Text:=intToStr(RW_byte[0]);
 end;
end;
//---------------------------Erstmal ohne Timer
procedure TForm2.Timer1Timer(Sender: TObject);
Var t:cardinal;
begin
 { Timer1.Enabled:=False;
    t:=GetTickCount;
    Eingang;
    Form2.Edit2.Text:=intToStr(RW_byte[0]);
    Timer1.Enabled:=True;
    Edit1.Text:=intTostr(GetTickcount-t);    }

end;
//--------------------------Thread Aktivieren
procedure TForm2.OnlineClick(Sender: TObject);
Var
Thread: TmyThread;
begin
 Thread:=Tmythread.Create(True);
 Thread.Resume;  // ich weiß nicht was das hier macht?
 end;
//-------------------------Thread Beenden
procedure TForm2.OfflineClick(Sender: TObject);
Var Thread:TmyThread;
begin
  Thread:=Tmythread.Create(False);
  
end;
//------------------------Form schliessen
 procedure TForm2.endeClick(Sender: TObject);
 begin
 close;
 end;
end.

Es passiert aber etwas nicht gutes. Wenn ich paar Mal zwischen Online und offline Umschalte kommt eine Fehlermeldung: (Eine Exception der Klasse EexternalException aufgetreten).
Woher kommt der Fehler?
Kann ich irgendwie die zeit noch verkürzen?


:rofl:

Moderiert von user profile iconNarses: Delphi-Tags hinzugefügt


Zuletzt bearbeitet von Omid am Mo 12.04.10 16:29, insgesamt 1-mal bearbeitet
ALF
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 1085
Erhaltene Danke: 53

WinXP, Win7, Win10
Delphi 7 Enterprise, XE
BeitragVerfasst: So 11.04.10 21:44 
Hi, sei so nett und packe den Code in Delphi-Tags ein, findest Du unter "Bereiche" oder schreibe
[delphi] dein Code [/delphi] sieht schöner aus :wink:

Schau Dir das hier mal an.
So wie Du es gemacht hast wird es nichts würde ich mal sagen.
Wobei ich fast der Meinung bin, das dies weniger mit Threads zu tun hat, als mit den ganzen Prodave wie Du es nutzen tust.

Gruss Alf

_________________
Wenn jeder alles kann oder wüsste und keiner hätt' ne Frage mehr, omg, währe dieses Forum leer!
Luckie
Ehemaliges Mitglied
Erhaltene Danke: 1



BeitragVerfasst: So 11.04.10 22:04 
Zeige uns doch endlich mal den Code von Eingabe. Eventuell lässt sich da noch was optimieren.
Xion
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
EE-Maler
Beiträge: 1952
Erhaltene Danke: 128

Windows XP
Delphi (2005, SmartInspect), SQL, Lua, Java (Eclipse), C++ (Visual Studio 2010, Qt Creator), Python (Blender), Prolog (SWIProlog), Haskell (ghci)
BeitragVerfasst: So 11.04.10 22:09 
user profile iconOmid hat folgendes geschrieben Zum zitierten Posting springen:
@ Xion
Ich habe die Zeitmessung wie du geschrieben hast, durchgeführt. Meine Prozedur Eingabe braucht 5949 ms. Wenn ich die Timer abstellen ändert sich die zeit nicht viel (ca. 15 ms).

Die Übertragung dauert 6 Sekunden. Dann ist ja logisch, dass du nicht alle 500ms und auch nicht alle 4*500ms = 2sekunden abrufen kannst. Egal welche Tricks dein Programm auch immer beherrscht.

user profile iconLuckie hat folgendes geschrieben Zum zitierten Posting springen:
Zeige uns doch endlich mal den Code von Eingabe. Eventuell lässt sich da noch was optimieren.

Jo, das wäre die einzige Möglichkeit. Oder du kannst die "Anlage" so umstellen, dass sie nicht so viele Daten senden soll. Mehr ist nicht drin.

Das ist wie wenn du schlechtes Internet hast, und dann deinen Browser umprogrammieren willst, damit du statt 1000er DSL plötzlich 16.000er DSL hast. Da kannst du lange am Browser basteln, das bringt nix ^^

_________________
a broken heart is like a broken window - it'll never heal
In einem gut regierten Land ist Armut eine Schande, in einem schlecht regierten Reichtum. (Konfuzius)
Narses
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Administrator
Beiträge: 10183
Erhaltene Danke: 1256

W10ent
TP3 .. D7pro .. D10.2CE
BeitragVerfasst: So 11.04.10 22:57 
Moin!

user profile iconLuckie hat folgendes geschrieben Zum zitierten Posting springen:
Zeige uns doch endlich mal den Code von Eingabe. Eventuell lässt sich da noch was optimieren.
user profile iconOmid hat folgendes geschrieben Zum zitierten Posting springen:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
procedure Eingabe;
Var
Abbyte,Anzahl:integer;
Begin
 // Werte Holen
     Abbyte:=124;
     Anzahl:=1;
     Res_R:= load_tool(1, addr(sps_name),addr(sps_adr_table[0]));
      if Res_R=0 then
      E_field_read(Abbyte,Anzahl,RW_byte);
      Res_R:=Unload_Tool;
end;
:nixweiss:

cu
Narses

_________________
There are 10 types of people - those who understand binary and those who don´t.
Xion
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
EE-Maler
Beiträge: 1952
Erhaltene Danke: 128

Windows XP
Delphi (2005, SmartInspect), SQL, Lua, Java (Eclipse), C++ (Visual Studio 2010, Qt Creator), Python (Blender), Prolog (SWIProlog), Haskell (ghci)
BeitragVerfasst: So 11.04.10 23:42 
Naja, das ist wohl kaum alles. E_field_read wäre interessant zu sehen

_________________
a broken heart is like a broken window - it'll never heal
In einem gut regierten Land ist Armut eine Schande, in einem schlecht regierten Reichtum. (Konfuzius)