| Autor |
Beitrag |
Omid
Hält's aus hier
Beiträge: 14
|
Verfasst: 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
      
Beiträge: 1054
Erhaltene Danke: 78
Win 7, Ubuntu 9.10
Delphi 2007 Pro, C++, Qt
|
Verfasst: 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
      

Beiträge: 10183
Erhaltene Danke: 1256
W10ent
TP3 .. D7pro .. D10.2CE
|
Verfasst: Di 06.04.10 20:23
Moin und  im Forum!
Da du noch Anfänger bist, versuch doch mal mit der TTIMER-Komponente regelmäßig eine Aktion auszuführen.  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 
Hält's aus hier
Beiträge: 14
|
Verfasst: 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.
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 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 Narses: Delphi-Tags hinzugefügt
|
|
Xion
      

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)
|
Verfasst: Mi 07.04.10 20:20
Omid hat folgendes geschrieben : |
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 
Hält's aus hier
Beiträge: 14
|
Verfasst: 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
      
Beiträge: 71
Erhaltene Danke: 4
Vista, Win XP, Win 89
Turbo Delphi Ex.
|
Verfasst: 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 
Hält's aus hier
Beiträge: 14
|
Verfasst: 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 
|
|
MaPsTaR
      
Beiträge: 90
Erhaltene Danke: 4
Win XP
Delphi 7 Enterprise
|
Verfasst: Sa 10.04.10 10:49
Wie bereits von Xion erwähnt, wird der Fehler wohl in Eingabe liegen.
Allerdings wird dir, ohne den Code dieser Prozedur, niemand groß weiterhelfen können.
Omid hat folgendes geschrieben : |
Delphi-Quelltext 1: 2: 3: 4:
| Procedure Eingang; Begin 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 
Hält's aus hier
Beiträge: 14
|
Verfasst: 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
      
Beiträge: 71
Erhaltene Danke: 4
Vista, Win XP, Win 89
Turbo Delphi Ex.
|
Verfasst: 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 
Hält's aus hier
Beiträge: 14
|
Verfasst: 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
      
Beiträge: 71
Erhaltene Danke: 4
Vista, Win XP, Win 89
Turbo Delphi Ex.
|
Verfasst: 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:
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 protected procedure Execute; override; end;
......
procedure TMyThread.Execute; begin while not Self.Terminated do begin DoSomething(); end; end; |
Und das zum starten:
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
      

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)
|
Verfasst: So 11.04.10 13:33
_________________ 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 
Hält's aus hier
Beiträge: 14
|
Verfasst: 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:
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 public end; var Form2: TForm2; implementation {$R *.dfm} uses pvar; procedure Eingabe; Var Abbyte,Anzahl:integer; Begin 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; procedure Tmythread.Execute; Begin while not self.terminated do begin Eingabe; Form2.Edit2.Text:=intToStr(RW_byte[0]); end; end; procedure TForm2.Timer1Timer(Sender: TObject); Var t:cardinal; begin end; procedure TForm2.OnlineClick(Sender: TObject); Var Thread: TmyThread; begin Thread:=Tmythread.Create(True); Thread.Resume; end; procedure TForm2.OfflineClick(Sender: TObject); Var Thread:TmyThread; begin Thread:=Tmythread.Create(False); end; 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?
Moderiert von Narses: Delphi-Tags hinzugefügt
Zuletzt bearbeitet von Omid am Mo 12.04.10 16:29, insgesamt 1-mal bearbeitet
|
|
ALF
      
Beiträge: 1085
Erhaltene Danke: 53
WinXP, Win7, Win10
Delphi 7 Enterprise, XE
|
Verfasst: 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
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
|
Verfasst: So 11.04.10 22:04
Zeige uns doch endlich mal den Code von Eingabe. Eventuell lässt sich da noch was optimieren.
|
|
Xion
      

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)
|
Verfasst: So 11.04.10 22:09
Omid hat folgendes geschrieben : | @ 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.
Luckie hat folgendes geschrieben : | | 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
      

Beiträge: 10183
Erhaltene Danke: 1256
W10ent
TP3 .. D7pro .. D10.2CE
|
Verfasst: So 11.04.10 22:57
_________________ There are 10 types of people - those who understand binary and those who don´t.
|
|
Xion
      

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