AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein GUI-Design mit VCL / FireMonkey / Common Controls Delphi Thread blockiert beim zweiten Aufruf von Synchronize
Thema durchsuchen
Ansicht
Themen-Optionen

Thread blockiert beim zweiten Aufruf von Synchronize

Ein Thema von hitzi · begonnen am 5. Nov 2008 · letzter Beitrag vom 6. Nov 2008
Antwort Antwort
Seite 1 von 2  1 2      
Benutzerbild von hitzi
hitzi

Registriert seit: 2. Jan 2003
Ort: Eibau
768 Beiträge
 
Delphi 2010 Professional
 
#1

Thread blockiert beim zweiten Aufruf von Synchronize

  Alt 5. Nov 2008, 14:03
Hallo,

folgender Code blockiert beim zweiten Aufruf/Durchlauf von Synchronize
Delphi-Quellcode:
procedure TWorkerThread.SyncGetNewEntries;
begin
  if Assigned(OnGetNewEntries) then OnGetNewEntries(fWorkList);
end;

procedure TWorkerThread.OnMainTimer(Sender: TObject);
begin
  fMainTimer.Enabled := False;
  if fTriesIt < 3 then begin
    if not StartWork(False, 3, False) then begin
      Inc(fTriesIt);
      fMainTimer.Interval := 60000;
    end else begin
      fTriesIt := 0;
      Synchronize(SyncGetNewEntries); //Erster Aufruf holt noch die Daten
                                      //beim zweiten Timerdurchlauf bleibt er an der Stelle ohne einen Fehler hängen/Programm
                                      //reagiert nicht mehr - wie bei einem Deadlock
      fMainTimer.Interval := 1000;
    end;
    if not fClosingTime then fMainTimer.Enabled := True;
  end;
end;

procedure TWorkerThread.Execute;
var i : Integer;
    msg : tagMSG;
begin
  fWorkList := TSLWorklist.Create;
  fHTTP := TIdHTTP.Create(nil);
  fMainTimer := TTimer.Create(nil);
  try
    fClosingTime := False;
    fMainTimer.Enabled := False;
    fMainTimer.Interval := 1000;
    fMainTimer.OnTimer := Self.OnMainTimer;
    fWaitMS := 5000;
    fHTTP.HTTPOptions := [{hoForceEncodeParams}];
    fMainTimer.Enabled := True;

    while GetMessage(msg, 0, 0, 0) do DispatchMessage(Msg);
    fClosingTime := True;
    fMainTimer.Enabled := False;
    if (fTriesIt < 3) and (fWorkList.Count > 0) then begin
      for i := 0 to fWorkList.Count - 1 do fWorkList.Items[i].ExecuteAfter := Now;
      StartWork(False, 1, True);
    end;
  finally
    fWorkList.Clear;
    FreeAndNil(fMainTimer);
    FreeAndNil(fHTTP);
    FreeAndNil(fWorkList);
  end;
end;
Ich hatte vorher diese Funktionen ohne Problem mit Sleep und ohne Timer genutzt, aber seit dem ich den Aufruf über den Timer mache bleibt es nach dem zweiten Durchlauf hängen. Seht ihr woran das liegen könnte?


Zusatz:

Der bleibt an der folgende Stelle in der Funktion TThread.Synchronize der Unit Classes hängen:
Delphi-Quellcode:
{$IFDEF MSWINDOWS}
        begin
          LeaveCriticalSection(ThreadLock);
          try
            WaitForSingleObject(SyncProcPtr.Signal, INFINITE); //hier wartet die Funktion ewig
          finally
            EnterCriticalSection(ThreadLock);
          end;
        end;
{$ENDIF}
Scheint irgendwie ein Deadlock eingetreten zu sein. Wie kann ich vorgehen, um das Problem zu lösen?
Thomas
Besucht doch mal http://www.hitziger.net
  Mit Zitat antworten Zitat
Benutzerbild von s.h.a.r.k
s.h.a.r.k

Registriert seit: 26. Mai 2004
3.159 Beiträge
 
#2

Re: Thread blockiert beim zweiten Aufruf von Synchronize

  Alt 5. Nov 2008, 14:35
ich versteh die verwendung deines timers nicht. brauchst du den unbedingt? ich kenne den kontext deines programms nicht wirklich.

was genau macht diese zeile, denn da wird wahrscheinlich der fehler stecken, bzw was genau ist dein code bei OnGetNewEntries.
if Assigned(OnGetNewEntries) then OnGetNewEntries(fWorkList); nutzt die critical sections, die du nicht mehr verlässt?
»Remember, the future maintainer is the person you should be writing code for, not the compiler.« (Nick Hodges)
  Mit Zitat antworten Zitat
Benutzerbild von hitzi
hitzi

Registriert seit: 2. Jan 2003
Ort: Eibau
768 Beiträge
 
Delphi 2010 Professional
 
#3

Re: Thread blockiert beim zweiten Aufruf von Synchronize

  Alt 5. Nov 2008, 14:43
Wie schon gesagt, hatte ich das vorher ohne Messageschleife und Timer gelöst, dafür aber mit Sleep(xy). Das Problem ist, dass bei einem Fehler (bei der Übermittlung der Daten im Thread an eine Webseite) die Zeit bis zum nächsten Versuch von von einer Sekunde auf 60 Sekunden geändert werden soll. Wenn ich das mit sleep(60000) mache und ich in der Zeit das Programm beenden möchte musste ich immer warten bis sleep() fertig war. Deshalb dachte ich mir, ich mach das jetzt mit einem Timer.
if Assigned(OnGetNewEntries) then OnGetNewEntries(fWorkList); OnGetNewEntries ist ein Ereignis, welches die Elternklasse aufruft neue Werte zu übergeben und mehr passiert da auch nicht. fWorklist ist ein array of record.

Critical Sections nutze ich selber nicht, dafür aber die Komponente idThread in einer anderen Unit im Programm (diese benutzt ja meines Wissens CriticalSections). Wie gesagt, es hat alles mit dem Code funktioniert - das einzige, was ich geändert habe ist der Aufruf über den Timer und die Messageloop.


EDIT: Ops .... "fWorklist ist ein array of record." ist falsch. fWorklist ist ne Klasse.
Thomas
Besucht doch mal http://www.hitziger.net
  Mit Zitat antworten Zitat
Benutzerbild von ChrisE
ChrisE

Registriert seit: 15. Feb 2006
Ort: Hechingen
504 Beiträge
 
Delphi 10.2 Tokyo Professional
 
#4

Re: Thread blockiert beim zweiten Aufruf von Synchronize

  Alt 5. Nov 2008, 15:45
Ich würde das Konzept umstellen:
1. Thread in Execute läuft mit while not Terminated
2. Intern mit TEvent warten auf:
A) Wurde TEvent ausgelößt -> Thread soll sich beenden
B) Auf den TimeOut -> jetzt hat dein Timer sozusagen zugeschlagen
3. Nach der Fallunterscheidung von dem Warten entsprechend Reagieren
A) Thread sicher zum "Ende" führen
B) Deine OnTimer-Methode hier aufrufen. Hier wird auch die nächste WarteZeit (TimeOut) für den nächsten Durchgang gesetzt.

Ich hoffe, das hilft dir.

Gruß, Chris
Christian E.
Es gibt 10 Arten von Menschen, die die Binär lesen können und die die es nicht können

Delphi programming rules
  Mit Zitat antworten Zitat
Benutzerbild von hitzi
hitzi

Registriert seit: 2. Jan 2003
Ort: Eibau
768 Beiträge
 
Delphi 2010 Professional
 
#5

Re: Thread blockiert beim zweiten Aufruf von Synchronize

  Alt 5. Nov 2008, 15:53
Einen schnellen Erfolg hab ich gerade mit der Klasse von Sirius. Diese ermöglicht das Synchronisieren ohne Synchronize und siehe da, damit funktioniert alles ohne Probleme und vor allem ohne Codeänderung? Komisch, oder? Synchronize hatte sonnst immer funktioniert. Werd mir das trotz allem noch ansehen. Irgendwo muss ja da trotzdem der Wurm drin sein.

Chris, meinst du dass so das Synchronize Problem behoben wird? Hmmm ... ausprobieren werde ich es auf alle Fälle mal.
Thomas
Besucht doch mal http://www.hitziger.net
  Mit Zitat antworten Zitat
Benutzerbild von ChrisE
ChrisE

Registriert seit: 15. Feb 2006
Ort: Hechingen
504 Beiträge
 
Delphi 10.2 Tokyo Professional
 
#6

Re: Thread blockiert beim zweiten Aufruf von Synchronize

  Alt 5. Nov 2008, 16:02
Zitat von hitzi:
Chris, meinst du dass so das Synchronize Problem behoben wird? Hmmm ... ausprobieren werde ich es auf alle Fälle mal.
Ich bin der Meinung, dass Dein Problem daher rührt, dass du einen Timer benutzt und mit der GetMessage etc. arbeitest. Das ist meiner Meinung nach in Threads nicht so gut. Threads dürfen ja quasi still stehen. Sie sind ja von Haus aus von der Applikation getrennt. Ich habe damit nur ins blaue geraten, da du ja quasi nur die Seite des Threads zeigst.
Ich würde es zumindest mal in dieser Richtung probieren und schauen was passiert

Gruß, Chris
Christian E.
Es gibt 10 Arten von Menschen, die die Binär lesen können und die die es nicht können

Delphi programming rules
  Mit Zitat antworten Zitat
Apollonius

Registriert seit: 16. Apr 2007
2.325 Beiträge
 
Turbo Delphi für Win32
 
#7

Re: Thread blockiert beim zweiten Aufruf von Synchronize

  Alt 5. Nov 2008, 17:41
Natürlich darf jeder Thread eine Nachrichtenschleife haben.

Der Punkt, an dem der Thread hängt, ist der normale Punkt, an dem ein Thread auf den Hauptthread wartet. Anscheinend kommt dein Hauptthread nicht mehr dazu, Application.Idle aufzurufen. Macht der Hauptthread irgendetwas besonderes, wenn der Arbeiterthread hängt?
Wer erweist der Welt einen Dienst und findet ein gutes Synonym für "Pointer"?
"An interface pointer is a pointer to a pointer. This pointer points to an array of pointers, each of which points to an interface function."
  Mit Zitat antworten Zitat
Benutzerbild von SirThornberry
SirThornberry
(Moderator)

Registriert seit: 23. Sep 2003
Ort: Bockwen
12.235 Beiträge
 
Delphi 2006 Professional
 
#8

Re: Thread blockiert beim zweiten Aufruf von Synchronize

  Alt 5. Nov 2008, 18:41
Ich hab das Gefühl der Messageloop + Syncronize nicht klappt. Wenn ich nicht ganz falsch liege arbeitet synronize intern auch mit Messages. Vielleicht geht da etwas scheif wenn der Messageloop schon was abholt.
Jens
Mit Source ist es wie mit Kunst - Hauptsache der Künstler versteht's
  Mit Zitat antworten Zitat
Apollonius

Registriert seit: 16. Apr 2007
2.325 Beiträge
 
Turbo Delphi für Win32
 
#9

Re: Thread blockiert beim zweiten Aufruf von Synchronize

  Alt 5. Nov 2008, 18:53
Nachrichtenschleifen zweier Threads sind vollkommen unabhängig. Außerdem arbeitet Synchronize nicht mit Fensternachrichten, sondern mit einer gelockten Liste.
Wer erweist der Welt einen Dienst und findet ein gutes Synonym für "Pointer"?
"An interface pointer is a pointer to a pointer. This pointer points to an array of pointers, each of which points to an interface function."
  Mit Zitat antworten Zitat
Benutzerbild von sirius
sirius

Registriert seit: 3. Jan 2007
Ort: Dresden
3.443 Beiträge
 
Delphi 7 Enterprise
 
#10

Re: Thread blockiert beim zweiten Aufruf von Synchronize

  Alt 5. Nov 2008, 19:26
Zitat von Apollonius:
Außerdem arbeitet Synchronize nicht mit Fensternachrichten, sondern mit einer gelockten Liste.
Mit beidem und einem Event. Sozusagen auf allen Kanälen.
Event setzen, WM_Null-Message an Application.Handle schicken und Medthode an Liste anhängen (in umgekehrter Reihenfolge).
Dieser Beitrag ist für Jugendliche unter 18 Jahren nicht geeignet.
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 2  1 2      


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 10:42 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