Announcement

Collapse
No announcement yet.

Thread und Messagebox

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • Thread und Messagebox

    hi,

    ich moechte einen Thread laufen lassen, der einige Datenbankabfragen macht. Dies soll alles in einer Unit stehen, damit meine kollegen diesen Thread einfach in ihr programm implementieren koennen. Also versuche ich, moeglichst viel Funktionalitaet hinein zu packen. U.a. soll eine Messagebox vor Anlaufen der Datenbankabfrage darauf hinweisen, ob die Abfrage ueberhaupt gestartet werden soll. Das passiert natuerlich im execute. Nachdem der Thread dann durch ist, ich warte im hauptformular auf das terminate(onterminate:=true), setze ich den Thread mit freeand nil ko. Anschliessend mache ich im Hauptformular ein paar Sachen, zeige z.B. die Daten im grid an usw. Dann bekomme ich ab und an eine Zugriffsverletzung. Soweit sichtbar habe ich aber alle Objekte sauber erzeugt und zerstoert.

    Koennte es sein, dass die Messagebox da Probleme bereitet? Wenn ja, was muss ich tun?
    (zwischendurch wird uebrigens via synchronize ein tcustommemo mit Statusmeldungen der Berechnung gefuellt, als auch, am Ende des Threads ein tstringlist.savetofile zum mitprotokollieren. Das fuellen des Memofeldes mache ich, indem ich eine tstringlist erzeuge, und dann via assign an das memo uebergebe).

    vielen dank

  • #2
    Da die MessageBox() nur entscheidet ob der Thread überhaupt ausgeführt werden soll, würde ich ihn noch vor dem TMyThread.Create() setzen. z.B.:

    <pre>

    type
    TMyThread = class(TThread)
    public
    class function CreateWithQuery: TMyThread;
    end;<br>

    class function TMyThread.CreateWithQuery: TMyThread;
    begin
    case MessageBox(0, 'Soll die Abfrage gestartet werden ?', ...) of
    mrYes: Result := Self.Create();
    else
    Result := nil;
    end;
    end;<br>

    </pre>

    Damit wird die MessageBox() immer im Aufrufenden Thread erzeugt, d.h. eigentlich immer im Hauptthread der Anwendung.<br>

    Gruß Hage

    Comment


    • #3
      Hallo Hagen,

      vielen Dank fuer die schnelle Hilfe, es scheint auch soweit zu funktionieren. Ich werde allerdings nicht aus diesem Class-Befehl schlau. Koenntest du mir mal bitte erklaeren, welche Bedeutung der hat? Die Erklaerung in der Hilfe ist mir unklar. Wieso verwendest du ihn hier in deinem Beispiel und was wuerde passieren, wenn man ihn wegliesse?

      mit Fragen ueber Fragen im Kopf,
      Andr

      Comment


      • #4
        Also der Unterschied wird deutlich im Aufruf der methode:

        <pre>

        var
        MyThread: TMyThread;
        begin
        // 1. Aufruf einer Klassenmethode
        MyThread := TMyThread.CreateWithQuery;<br>

        // 2. Aufrur falls es keine Klassenmethode ist
        MyThread := TMyThread.Create;
        MyThread.CrateWithQuery;
        end;

        </pre>

        Wie du siehst im 1. Aufruf benötigt man KEIN Object sondern arbeitet mit der Klasse des Objectes, so als ob man mit Objecten arbeitet. Klassenmethoden sind also Methoden die wie normale Methoden virtual sein können. Da Klassenmethoden mit Klassen arbeiten heist das daß mit einer virtuellen Klassenmethode die Klasse an sich ebenfalls polymorph benutzt werden kann.<br>
        Das OOP definiert Klassen = "Objecttypen" und Objecte. Die Klassen sind die Gußformen und ein Speicherbereich der mit dieser "Gußform" erzeugt wurde, ist ein Object der Klasse. Beide können virtuelle Methoden enthalten und somit polymorph verwendet werden, aber NUR ein Object kann eigene private Variablen enthalten. Eine Klasse hätte wenn überhaupt nur statische Klassenvariablen. D.h. innerhalb einer Klassenmethode zeigt der unsichtbare Self-Zeiger auf die Klasse statt dem Object.<br>

        Polymorphe Klassen:

        <pre>
        type
        TPersistentClass = class of TPersistent;

        var
        Class: TPersistenClass;
        Peristent: TPersistent;
        begin
        if Query then Class := TFont
        else Class := TBitmap;<br>

        Persistent := Class.Create;
        end;

        </pre>

        Wie du oben siehst, enthält eine Variable "Class" die Klasse des zu erzeugenden Objectes. Mit Class.Create() -> "erzeuge Object vom Objecttyp der in der Variablen Class gespeichert ist", wird das Object erzeugt.<br>
        Dieses Verhalten ist extrem wichtig, da z.B. das ganze VCL Streamingsystem, sprich die DFM's, darauf aufbauen. Ohne Klassen könnte das nicht funktionieren.<br>
        Man erkennt sehr schnell das "Object Orientiertes Programmieren" eigentlich KOP -> "Klassen orientieres Programmmieren" heissen sollte. Objecte sind echt "dumm" da sie nur das können was wir als Programmieren der Klasse des Objectes vorher deklariert haben. Im Grunde sind es die Klassen die vererbt werden, die virtuelle, dynamische Methoden haben, und die EINDEUTIG sind und nur EINMAL pro Anwendung existieren. Ein Object kann gar nichst, nur die dynamischen Daten werden privat zum Object verwaltet. Von einer Klasse können unendlich viele Object"clone" existieren. Klassen wiederum können keine Daten enthalten, d.h. innerhalb der Klassenmethode kann man keinerlei Felder ansprechen. Das liegt daran das "Self" nun kein Zeiger auf ein Object im Speicher ist, sondern ein Zeiger auf den "Speicher" der Klassendefinition. Dieses "Self" enthält die RTTI,VMT,DMT,Interfaces usw. usw, ABER KEINE Felder.<br>

        Gruß Hage

        Comment


        • #5
          klasse,
          vielen Dank. Der Unterschied zwischen Klasse und Objekt war mir klar, aber ich werde das Gefuehl nicht los, dass, abhaengig von der Prog-Sprache, die Dinge unterschiedlich bezeichnet werden.
          Also nochmals vielen Dank fuer deine Hilfe. Die hat mal wieder eine kleine Lampe bei mir angeknipst.

          Andr

          Comment

          Working...
          X