![]() |
Anonymous Methods für Sanduhr als Design Pattern
ich würde gerne alle SQL Operationen in meinem Programm via Anonymous Methods als Design Pattern mit einem Mauszeiger ausstatten.
Ich habe folgenden Code hierzu :
Delphi-Quellcode:
type
TQueryProc = reference to procedure (aQuery: TADOQuery); procedure ShowHourGlassDuringSQL(Proc: TQueryProc); var OldCursor: TCursor; begin OldCursor := Screen.Cursor; Screen.Cursor := crHourGlass; try Proc; finally Screen.Cursor := OldCursor end; end; TMainform.ExecuteSQL1(aQuery : TADOQUERY); begin .... end; TMainform.ExecuteSQL2(aQuery : TADOQUERY); begin .... end; TMainform.ExecuteSQL3(aQuery : TADOQUERY); begin ..... end; der eigenliche Code wäre dann :
Delphi-Quellcode:
Ich bekomme noch nicht mal die korrekte Syntax hin, was mache ich falsch?
ShowHourGlassDuringSQL(MyMainForm.ExecuteSQL3(meineQueryA));
ShowHourGlassDuringSQL(MyMainForm.ExecuteSQL3(meineQueryB)); |
AW: Anonymous Methods für Sanduhr als Design Pattern
Delphi-Quellcode:
unit Unit1;
interface uses System.Classes, Vcl.Controls, Vcl.Forms; type TADOQuery = class end; TQueryProc = reference to procedure(aQuery: TADOQuery); TForm1 = class(TForm) procedure FormCreate(Sender: TObject); private public procedure ExecuteSQL1(aQuery: TADOQuery); procedure ExecuteSQL2(aQuery: TADOQuery); procedure ExecuteSQL3(aQuery: TADOQuery); end; var Form1: TForm1; implementation {$R *.dfm} procedure ShowHourGlassDuringSQL(const Proc: TQueryProc; const Query : TADOQuery); var OldCursor: TCursor; begin OldCursor := Screen.Cursor; Screen.Cursor := crHourGlass; try Proc(Query); finally Screen.Cursor := OldCursor end; end; procedure TForm1.ExecuteSQL1(aQuery: TADOQuery); begin end; procedure TForm1.ExecuteSQL2(aQuery: TADOQuery); begin end; procedure TForm1.ExecuteSQL3(aQuery: TADOQuery); begin end; procedure TForm1.FormCreate(Sender: TObject); var LQuery: TADOQuery; begin LQuery:= TADOQuery.Create; ShowHourGlassDuringSQL(ExecuteSQL1, LQuery); ShowHourGlassDuringSQL(ExecuteSQL2, LQuery); ShowHourGlassDuringSQL(ExecuteSQL3, LQuery); end; end. |
AW: Anonymous Methods für Sanduhr als Design Pattern
Dafür benötigt man keine anonymen Methoden -
![]() |
AW: Anonymous Methods für Sanduhr als Design Pattern
Bei der Gelegenheit:
![]() |
AW: Anonymous Methods für Sanduhr als Design Pattern
Oder andersrum, also in etwa so?
Delphi-Quellcode:
procedure Test1;
begin THourGlass.Create; // mach was end; // THourGlass setzt sich am Funktions-Ende selber zurück procedure Test2; var HourClass: IHourClass; begin HourClass := THourGlass.Create; // mach was HourClass := nil; // THourGlass manuell zurücksetzen // mach nochwas end;
Delphi-Quellcode:
Oder als externe
type
IHourClass = IInterface; THourGlass = class(TInterfacedObject {, IHourClass}) private class var FInstances: Integer; FOldCursor: TCursor; public class function Create: IHourClass; reintroduce; static; destructor Destroy; override; end; class function THourGlass.Create: IHourClass; begin Result := inherited THourGlass.Create; //Result := THourGlass(NewInstance); if InterlockedIncrement(FInstances) = 1 then Result.FOldCursor := Screen.Cursor; Screen.Cursor := crHourGlass; end; destructor THourGlass.Destroy; begin if InterlockedDecrement(FInstances) = 0 then Screen.Cursor := FOldCursor; inherited; end;
Delphi-Quellcode:
und die Klasse in Implementation verschieben/verstecken.
function SetHourGlass: IHourGlass;
Bei der Funktion kann man das auch leichter als Singleton implementieren. (darf da nur nicht die globale Singleton-Instanz vergessen mitzuzählen) |
AW: Anonymous Methods für Sanduhr als Design Pattern
@Stevie:
Ich hab mir mal den Fun Code geholt und in mein Programm eingebaut. Ich muss vorweg schicken, dass ich "Old-School" bin und deshalb leider noch rein gar nichts mit Interfaces zu tun gehabt habe. :cry: Wenn ich es richtig verstehe, kann ich die Funktion AutoCursor innerhalb einer Methode XY aufrufen und innerhalb der selben Methode anschliessend z.B. eine Tabelle laden. Sobald XY beendet ist, also das AutoCursor-Interface innerhalb des Scope von XY nicht mehr referenziert wird, wird der Cursor restauriert und das Interface frei gegeben. Ist das korrekt? :roll: Wenn ja, dann müsste es analog funktionieren wie den Cursor zu setzen und anschliessend innerhalb eines try...finally Blocks die Tabelle zu laden und den Cursor wieder zurück zu setzen. Leider ist aber mit AutoCursor nichts zu sehen vom geänderten Cursor. Wenn ich einen Haltepunkt setze, scheint das Programm so zu laufen wie im vorhergehenden Absatz beschrieben. Das wird auch bestätigt, wenn ich zu Testzwecken am Ende von XY noch ein kleines Sleep einbaue. Dann kann ich, wie beim try...finally Block das Setzen und Rücksetzen des Cursors verfolgen. Mache ich einen Denkfehler oder habe irgendetwas übersehen? Hättest Du vielleicht ein kleines Codebeispiel, in dem der gewünschte Effekt nachvollziehbar ist? Vielen Dank! |
AW: Anonymous Methods für Sanduhr als Design Pattern
himitsu's Ansatz ist "eigentlich" besser, da die Procedure beliebig oft aufgerufen werden kann...
Wenn man zwischen durch aber einen anderen Cursor braucht, geht das so leider nicht. Mit dem AutoCursor ist das auch ganz nett und kann somit auch verschiene zwischen Cursor darstellen und restaurieren.. Keinens der Beispiele ist jedoch Thread geeignet. Da man gerade Datenbankzugriffe gerne in einen Thread verlagert, sollte das Cursor setzen Threadsave sein. Oder muss die Threadgeschichte außen drum, weil der Cursor nichts damit zu tun hat? Geschmacksache... Mavarik |
AW: Anonymous Methods für Sanduhr als Design Pattern
Einen Thread-Status würde ich aber nicht mit dem Mauszeiger darstellen ... außer den des Hauptthreads.
Also wenn das in Threads aufgerufen wird, dann würde ich dann die Funktions sperren und in Threads den Mauszeiger einfach nicht ändern. |
AW: Anonymous Methods für Sanduhr als Design Pattern
Der Cursor gehört zur Anwendung und ändert die Anzeige. Ergo kann man das zum UI zählen.
Ändert man UI relevante Dinge in einem Thread? Generell nein. Aber wie denn dann? Recht simpel von der Theorie: Mit dem Cursor zeigt man einen Status der Anwendung an (beschäftigt, SQL Abfrage läuft, ...). Wenn man sich jetzt ein
Delphi-Quellcode:
schafft und dort tragen alle Threads ein, was diese gerade machen (einfach nur arbeiten, SQL-Abfrage, ...), dann kann man den höchsten Status ermitteln und entsprechend anzeigen (jeweils im Idle-Event der Anwendung).
TApplicationState
|
AW: Anonymous Methods für Sanduhr als Design Pattern
Nur noch mal als Ergänzung zu meinem Beitrag von gestern. Natürlich lag das Problem wie so oft zwischen den Ohren. :cyclops:
Das Laden der Tabelle ging so schnell, dass das Hin- und Herschalten des Mauszeigers nicht wahrnehmbar war. Und den Eindruck, dass das mit dem try...finally Block anders wäre, hatte ich natürlich auch exklusiv. :oops: Also, langer Rede, kurzer Sinn. AutoCursor verhält sich genau wie in meinem ersten Beitrag beschrieben und liefert identische bzw. zumindest kompatible Ergebnisse. Ob nun aber die Verwendung eines solchen Interface zu Aussagen wie "the resulting code is simpler and easier to manage" berechtigt, erschliesst sich mir noch nicht so ganz. Das Zitat stammt aus Nick Hodges' Buch "Coding in Delphi" von dem ich mir gerade eine Leseprobe angesehen habe. Zumindest kapiere ich inzwischen aber, dass Interfaces ein Segen für Dependency Injection, Mocking und Testing sind. Hier kann ich mit Sicherheit noch eine Menge lernen! :stupid: |
AW: Anonymous Methods für Sanduhr als Design Pattern
Hallo Sir Rufo!
Interessanter, weil im Prinzip so simpler Ansatz! :thumb: Ähnliche Überlegungen sind auch hinsichtlich Anzeige in der Statuszeile anzustellen, sofern man denn eine solche in seinem Hauptformular verwendet. Wenn ich das jetzt mal weiter spinnen darf. Eine public property AppStatus des Hauptformulars würde sogar einen Zugriff "von aussen" erlauben. Also z.B. wenn es eine Kreuz-Referenz zwischen Hauptformular und zugehörigen Dialogen gibt. Dialoge könnten beim Öffnen den Status direkt setzen oder vielleicht noch besser eine entsprechende Message schicken. Der Setter der property kümmert sich dann um die Anzeige in der Statuszeile und den Mauszeiger. Ob und wie das ganze dann noch mit Application.Idle zusammen zu bringen ist, wäre die Fleissaufgabe. Hast Du das schon einmal so realisiert? Wenn ja, würdest Du eventuell Code dazu posten? Vielen Dank! |
AW: Anonymous Methods für Sanduhr als Design Pattern
Zitat:
Daher würde ich es: 1. Über ein Interface realisieren damit ich mir das AutoFreeOnOutOfScope damit einkaufe.. 2. Im Object setze ich nicht den Cursor selber, sondern sende eine TMessage. Hierauf kann meine UI Thread reagieren und dann mit der Info mach was sich möchte... Cursor ändern, Etwas in der Statusliste ausgeben... ggf. in ein Log usw... 3. Ich kann - falls die "Gefahr" besteht, dass es auch einem Threads kommen kann, dann bemühe ich den ![]() Bingo... |
AW: Anonymous Methods für Sanduhr als Design Pattern
Ich würde einfach eine Presenter Instanz schaffen (jeweils für VCL/FMX) und diese prüft dann bei einer IdleMessage, ob der Status (Cursor) geändert werden muss und der ändert dann bei Bedarf.
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 09:04 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 by Thomas Breitkreuz