AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren

Funktionsliste

Ein Thema von DelphiManiac · begonnen am 25. Sep 2006 · letzter Beitrag vom 26. Sep 2006
Antwort Antwort
DelphiManiac

Registriert seit: 5. Dez 2005
742 Beiträge
 
#1

Funktionsliste

  Alt 25. Sep 2006, 10:51
Hallo,

ich bin gerade dabei ein Anwendungsprogramm für eine Hardware zu entwickeln.

Kommuniziert wird wahlweise mit USB oder COM.

Zurzeit habe ich meine Kommunikation noch im Hauptthread.

Ich habe nun folgendes vor und hoff ihr könnt mir ein paar Tipps geben:

Nach dem Verbinden mit dem Gerät werden ersteinmal ein paar grundlegende Daten vom Gerät gelesen.

--> Danach sollen je nach Maske andere Werte zyklisch gelesen werden.
--> Dazwischen muss es immer wieder möglich sein Werte zu ändern und einen Schreibbefehl zwischen den anderen Lese-
Befehlen abzusetzten.

Ich würde die gesamte Kommunikation gerne in einen extra Thread programmieren.
Zurzeit habe ich noch folgendes Konstrukt:

Delphi-Quellcode:
Get_SoftwareRelease(release);
label_softwarerelease.Caption:=release;
..
Get_SoftwareSubRelease(subrelease);
label_subrelease.Caption:=subrelease;
..
usw...
Wie kann ich denn Labels in eines anderen Threads in dem die VCL läuft aktualiseren und wie gebe ich das meinem Thread mit??

Desweiteren würde ich gerne eine Jobliste anlegen..., die alle Funktionen enthält, die gerade benötigt werden und nacheinander abgearbeitet werden.
Beispiel
Jobliste[0]:=Get_SoftwareDatum;
Jobliste[1]:=Get_SoftwareVersion;
usw..

Hoffe ihr könnt mir helfen..
Danke schonmal im Vorraus
  Mit Zitat antworten Zitat
berens

Registriert seit: 3. Sep 2004
434 Beiträge
 
Delphi 10.4 Sydney
 
#2

Re: Funktionsliste

  Alt 25. Sep 2006, 11:24
Ich bin in dem Bereich natürlich nicht der Fachmann, aber ein paar Ansatzpunkte, die Dir vielleicht helfen können:

-dein abgeleiteter Thread kann ja auch die Labels als Objekte haben, die "Verweise" auf die Labels des Hauptformulars sind. Mit denen kannst du dann intern arbeiten.

Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);
var
  t: TMyThread;
begin
  t := TMyThread.Create(True);
  t.Label1 := Form1.Label1;
  t.Label2 := Form1.Label2;
  // etc.
end;


procedure TMyThread.Sync;
begin
  Label1.Caption := 'Bla' + IrgendEineStringVaribaleAusDiesemThread;
  // etc.
end;

procedure TMyThread.Execute;
begin
  // IrgendWas
  IrgendEineStringVaribaleAusDiesemThread := 'Foo';
  Synchronize(Sync);
  // IrgendWas
end;
Beachte dass Änderungen an visuellen Komponenten durch Threads generell nur durch den Aufrufen von einer Prozedur/Funktion mit dem Befehl "Synchronize" durchgeführt werden durfen. (Sonst Absturz!).

-deine Aufgabenliste kann man eventuell als Array of TProcedure machen und diese dann auch so direkt wieder aufrufen:
Delphi-Quellcode:
var // Global
  arrProc: array of TProcedure;

procedure Jobliste_Abarbeiten;
begin
for i := low(arrProc) to high(arrProc) do begin
  if assigned(arrProc[i]) then begin
    arrProc[i];
  end;
end;
^-- ungetestet, keine Ahnung ob das so direkt geht...
  Mit Zitat antworten Zitat
TAC

Registriert seit: 29. Nov 2005
Ort: Hamburg
25 Beiträge
 
#3

Re: Funktionsliste

  Alt 25. Sep 2006, 11:37
Ich bin mir zwar nicht ganz sicher, aber ich glaube mich erinnern zu können, daß man nicht unbedingt aus einem Thread heraus zeichnen controls anteuern sollte. Würde daher also dem Thread ein Event hinterlegen, welches dann vom Form aus gesetzt wird. Dies sollte dann eigentlich keine Fehler beim Aktualiseren der visuellen Komponenten hervorrufen.



type Tmythreadevent = procedure (Sender:TObject;wert1,wert2,wert3,wert4 {...} : String) of object;

tmythread
....
onMyEvent : Tmythreadevent;


tform
...
procedure onThreadEvent (Sender:TObject;wert1,wert2,wert3,wert4 {...} : String)
...
tmytherad.onmyevent := onThreadEvent ;


procedure onThreadEvent (Sender:TObject;wert1,wert2,wert3,wert4 {...} : String)
begin
label1.caption := wert1;
....
end;


MFG
TAC
  Mit Zitat antworten Zitat
Der_Unwissende

Registriert seit: 13. Dez 2003
Ort: Berlin
1.756 Beiträge
 
#4

Re: Funktionsliste

  Alt 25. Sep 2006, 12:09
Hi,
dein Ansatz die Kommunikation komplett von der Form zu trennen ist doch schon mal gut! Den solltest du aber auch konsquent einhalten. So ist es zwar mögllich dem Thread hier noch Referenzen auf Controls zu geben, aber die Frage ist viel mehr, ist das nötig?

Du solltest vielmehr mit einer Art Call-Back arbeiten. Dein Thread übernimmt dabei (von aussen angestossen) die Kommunikation, wurde ein Wert abgeholt, dann benachrichtigt der einfach jeden der sich dafür interessiert. Im einfachsten Fall nimmst du einfach einen Funktionszeiger und rufst eine Funktion in deinem Formular auf, dass dann diesen Wert als Caption eines Labels verwendet, du kannst aber auch gleich ein Observer-Pattern implemtieren (z.B. eine Liste von Funktionszeigern oder halt ein Interface/eine Basisklasse die eine bestimmte Methode hat, die dann aufgerufen wird).

Jedenfalls kannst du durch eine solche Trennung dann leicht das Design des Formulars ändern. Da die Kommunikation nichts mit dem Aussehen zu tun hat, hast du so nichts anzupassen. An sich solltest du das immer versuchen durch zu halten.

Gruß Der Unwissende
  Mit Zitat antworten Zitat
DelphiManiac

Registriert seit: 5. Dez 2005
742 Beiträge
 
#5

Re: Funktionsliste

  Alt 25. Sep 2006, 13:15
@Der_Unwissende:

Hallo Danke erstmal für eure Antworten!!!

Ich bin schonmal froh, dass mein Ansatz "Design von Logik zu trennen" schonmal nicht ganz so falsch ist
Allein mit der Umsetzung hapert es noch.

@Der_Unwissende:
Hast du evtl ein Beispielcode für die Callback Methode und das mit dem "Observer-Pattern" .

Ich google mal, wäre aber trotzdem super wenn du mir da noch einen Schupps geben könntest.


Vielen Dank schonmallllll
  Mit Zitat antworten Zitat
Der_Unwissende

Registriert seit: 13. Dez 2003
Ort: Berlin
1.756 Beiträge
 
#6

Re: Funktionsliste

  Alt 25. Sep 2006, 13:50
Zitat von DelphiManiac:
@Der_Unwissende:
Hast du evtl ein Beispielcode für die Callback Methode und das mit dem "Observer-Pattern" .

Ich google mal, wäre aber trotzdem super wenn du mir da noch einen Schupps geben könntest.
Erstmal zu den Callbacks (sorry, wird mal etwas unsauber, bin auf'm Sprung):
Delphi-Quellcode:
type
  TDeinCallBack = procedure(const neuerWert : TTyp) of Object;
So legst du einen Methodenszeiger an. Dieser speicher die Adresse einer Funktion/Prozedur einer Klasse. Du legst jetzt eine Variable von diesem Typ in deinem Thread an. Die Parameter (hier neuerWert) geben dabei die Nachricht weiter (was genau ist passiert). Hier könntest du z.B. einen Messwert übergeben, der angezeigt oder gespeichert werden soll.
In deiner Form legst du dann eine Methode mit dieser Signatur an
Delphi-Quellcode:
type
  TForm1 = class(TForm)
   ...
   procedure onWhatEver(const neuerWert : TTyp);
Diese Prozedur kannst du nun der Variable des Threads vom Typ TDeinCallback zuweisen (:= Form1.onWhatEver Also ohne Klammern und Argument. Wie gesagt, du speichert damit eine Adresse, assigned gibt dir also zurück, ob dieser Zeiger gültig ist oder nicht. Ist er gültig, kann dein Thread diese Methode einfach aufrufen. Dazu einfach diese Variable wie eine echte Methode verwenden. Damit muss dein Thread also gar nicht wissen wo die Funktion herkommt. Er hat einfach eine Adresse und ruft die entsprechende Methode auf. Die kannst dann auch aus Form2, Fomr3 oder DoFoo28737 kommen, hauptsache es ist eine Methode, die genau diese Signatur hat.

Das Observerpattern ist hingegen nur ein Muster. Hier wird vorgegeben, wie man mehr als einen Beobachter über ein Ereignis informieren kann, die Implementierung hingegen bleibt einem selbst überlassen. Das was ich noch ansprach (über Objekte) werde ich hier auch nochmal posten, aber jetzt muss ich erstmal weiter.
  Mit Zitat antworten Zitat
DelphiManiac

Registriert seit: 5. Dez 2005
742 Beiträge
 
#7

Re: Funktionsliste

  Alt 26. Sep 2006, 10:43
@der_Unwissende:

Hi, danke dass du dir nochmal Zeit genommen hast für mein Problem, obwohl du gerade aufm Sprung warst.


habe aber noch ein paar Questions an dich:
-->
Delphi-Quellcode:
type
  TDeinCallBack = procedure(const neuerWert : TTyp) of Object;
Hier lege ich einen Type TDeinCallBack an, der einen Funktionszeiger (Adresse einer Funktion/Prozedur) speichert.
Habe ich das richtig verstanden?
Der Vorteil hier ist es ,dass ich eine Funktion übergeben kann an meinen Thread???
Wast ist denn genau mit const neuerWert : TTyp gemeint?

Naja werde jetzt nich gleich den Sand in den Kopf stecken (wie Lothar Matthäus )


DAAAANKE
  Mit Zitat antworten Zitat
DelphiManiac

Registriert seit: 5. Dez 2005
742 Beiträge
 
#8

Re: Funktionsliste

  Alt 26. Sep 2006, 11:03
Hallo,

die Prozedurezuweisung hat irgendwie nicht geklappt,

nachdem ich das of Object weggelassen habe konnte ich die Prozeduren zuweisen.

Kannst du mir erklären für was das of Object zuständig ist?

Gracias
  Mit Zitat antworten Zitat
TAC

Registriert seit: 29. Nov 2005
Ort: Hamburg
25 Beiträge
 
#9

Re: Funktionsliste

  Alt 26. Sep 2006, 11:36
Moin,

mit dem of object wird ein Methodenzeiger erzeugt, der über den Type TDeinCallBack verfügbar ist.
In der Threadklasse wird dann das EventOnDeinCallBack : TDeincallback; implementiert, sinnvollerweise public, damit der Instanz von TMyThread von außen für OnDeinCallBack etwas zugewiesen werden kann.
In einer anderen Klasse (z.B. Form1) deklariert man dann z.B. eine entsprechende procedure MeinThreadMeldetSich(const neuerWert : TTyp) .

Wenn man nun in OnCreate des Form1 den MyTHread := Thread.Create... kreiert , dann macht man hier die Zuweisung MyThread.OnDeinCallBack := MeinThreadMeldetSich; .
Wenn man zudem, wie ich es zuvor vorgeschlagen hatte, den Sender in den Methodenzeiger implementiert, dann hat Form1 auch direkten Zugriff in MeinThreadMeldetSich auf den Thread selbst und nicht über die Instanz MyThread . Dies macht dann Sinn, wenn vielleicht mehrere Threads gleichzeitig laufen, und man nicht unbedingt weiß, welcher gerade MeinThreadMeldetSich aufruft, dann lässt sich über Sender auf die jeweilige Instanz bezugnehmen. Wie z.B. wenn alle Button es Form1 dasselbe ClickEvent OnClick aufrufen, lässt sich in der Procedure Tform1.ButtonClickEvent(Sender:TObject) z.B. mit showmessage((Sender as TButton).name) ausgeben.

Hoffe, daß hat ein wenig helfen können...

Mfg
TAC
  Mit Zitat antworten Zitat
Themen-Optionen Thema durchsuchen
Thema durchsuchen:

Erweiterte Suche
Ansicht

Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 05:51 Uhr.
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