Announcement

Collapse
No announcement yet.

Thread blockiert beim Senden vom EMails, aber warum ?

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

  • Thread blockiert beim Senden vom EMails, aber warum ?

    Hy!

    Ich habe mir jetzt das Buch über Win32-Lösungen von Andreas Kosch
    bestellt, ich kann aber nicht auf die Lieferung warten, denn ich
    habe ein kleines Problem, dessen Lösung ich gleich benötige:

    Ich verwende die Indy Komponenten zum Versenden von EMails.
    Dabei erzeuge ich einen eigenen Thread zum Versenden.
    Innerhalb des Threads wird die Mail zusammengestellt,
    die Verbindung zum SMTP-Server hergestellt und die Mail versendet.
    Funktioniert alles bestens, ausser ich versenden sehr grosse
    Attachments mit (z.B. 10Mb). Dann steht nämlich die Hauptanwendung.
    Ich verwende weder Synchronize (denn das würde blockieren)
    noch TAntiFreeze von Indy (das würde die Anwendung nicht blockieren),
    denn TAntiFreeze funktioniert nicht im Thread.

    Es ist mir übrigends schon einmal aufgefallen, dass separate Threads
    scheinbar meine Hauptanwendung kurzzeitig blockieren,
    obwohl die Threads weder auf Komponenten oder Eigenschaften der Hauptanwendung zugreifen, noch mit Synchronize arbeiten.

    Was könnten die Gründe dafür sein, dass ein Thread meine Hauptanwendung
    blockiert? Was passiert, wenn ich eine Komponenten innerhalb eines
    Threads erzeuge und dabei als Owner nil angebe? Liegt hier vielleicht
    das Problem?

    Danke
    Schardl Robert

  • #2
    Hi

    Es ist absolut entscheidend was im Thread alles ausgeführt wird. Irgend eine der Indy-Unterfunktionen könnte mit SendMessage(), CriticalSections/Pipe etc. arbeiten und somit eine implizite Synchronisation/Blocking des MainThreads bewirken.
    D.h. man sollte die kompletten Sourcen vorliegen haben und dann Schritt für Schritt eine Analyse durchführen.

    Gruß Hage

    Comment


    • #3
      Hy Hagen!

      Danke für die schnelle Antwort!

      Ich habe nichts verdächtiges finden können im Source-Code.
      Vielleicht ist auch mein Thread falsch.

      Im MainThread wird ein Thread gestartet.
      Ich übergebe dem Thread einen Pointer auf eine Collection,
      welche im MainThread erzeugt wurde.
      Der Thread selbst erzeugt mehrere Datenbankkomponenten, darunter
      auch ein IBEvent Objekt, welches auf Events der Interbase
      Datenbank reagiert. Des weiteren wird ein Timer erzeugt.
      Wenn ich nun einen neuen Datensatz anlege, erhält das IBEvent
      Objekt eine Benachrichtigung. Die Benachrichtigung wird dann in einer
      Liste zwischengespeichert. Jetzt kommt der Timer ins Spiel.
      Alle x Sekunden prüft der Timer ab, ob in der Benachrichtigungsliste
      eine neue Benachrichtigung steht. Wenn nein, passiert nichts.
      Wenn ja, dann ruft der Timer eine Funktion innerhalb des Threads
      auf. Diese Funktion sendet dann z.B. EMails, oder prüft gewisse
      Dinge in der Datenbank ab (eigene TSession!!).

      procedure TheThread.Create .....
      begin

      IBDB:=TIBConnection.Create...
      .....
      .....
      fTimer:=TTimer.Create(nil);
      fTimer.OnTimer:=CheckMessages;
      ......
      inherited Create(false);
      end;

      procedure TheThread.Execute()
      begin
      DB.Connect .... usw.
      IBEvents.RegisterEvents;
      fTimer.enabeld:=true;
      end;

      Vielleicht ist auch die Verwendung des Timer falsch?
      Wenn ja, was kann ich statt dem Timer verwenden?
      Die Realisierung innerhalb von Execute schien mir
      nicht sehr gut ->
      while not Terminated do ChechMessages();
      da ich ja nur
      alle 10 oder 60 Sekunden (je nach Umfeld) die Prüfung erfolgen
      lassen will.

      Danke!
      Robert Schard

      Comment


      • #4
        Hi

        Auf den Timer kannst'e verzichten:

        <pre>

        procedure TMyThread.Execute;
        const
        Delay = 60000; // 60 Sekunden
        var
        FTickCount: Integer;
        begin
        FTickCount := GetTickCount + Delay;
        while not Terminated do
        begin
        if GetTickCount >= FTickCount then
        begin
        CheckMessages;
        FTickCount := GetTickCount + Delay;
        end else Sleep(50);
        end;
        end;

        </pre>

        In CheckMessages sollte kein .Synchonize(), SendMessage, GetMessage(), Application.ProcessMessages etc. benutzt werden. Es kann aber durchaus sein das die Windows API Funktionen der Sockets den aufrufenden Prozess blockieren, egal aus welchem Thread.

        Gruß Hage

        Comment


        • #5
          Achso, wie erstellst/zerstörst Du Dein TThread Object ?
          Rufst Du MyThread.Execute aus dem MainThread auf

          Comment


          • #6
            Hallo Hagen!

            Vielen Dank für die Info und Deine Hilfe.

            Application.ProcessMessages verwende ich im Thread für die
            Aktualisierung der Message-Texte in der StatusBar.
            Ich habe nun herausgefunden, dass die Blockierung dezitiert
            in den Indy-Komponenten TIdMessageClient.SendMsg stattfindet.
            Ich habe auch schon versucht, die Priorität des MainThreads
            hinaufzusetzen, leider ohne Erfolg.
            Auch die Verwendung der Klasse TIdAntiFreeze von Indy, welche
            nichts anderes macht, als
            if PeekMessage(Msg, 0, 0, 0, PM_NOREMOVE) then
            Application.HandleMessage;

            Execute wird automatisch von Create aufgerufen ->
            inherited Create(false).
            Ich werde mal den Timer entfernen und die "Schleife" in die
            procedure Execute legen.
            Dies wird aber nicht die Lösung sein.

            Da der Thread DBEvents prüft und ich diese Prüfungen immer
            benötige, wird der Thread erst beim Beenden das MainThreads
            zerstört mittels
            TheThread.Terminate;
            TheThread.Free;

            Ich glaube, dass die API den Prozess blockiert.

            Keine Ahnung, wie ich das "wegbekomme".

            Danke.
            Robert Schard

            Comment


            • #7
              Hallo Hagen!

              Danke nochmal für Deine Hilfe!

              DER TIMER BLOCKIERT DEN THREAD!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

              Danke
              Robert Schard

              Comment

              Working...
              X