Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Programmieren allgemein (https://www.delphipraxis.net/40-programmieren-allgemein/)
-   -   Problem mit Critical Section (https://www.delphipraxis.net/115119-problem-mit-critical-section.html)

DoktorD 6. Jun 2008 07:40


Problem mit Critical Section
 
Hi.

Ich habe ein RichEdit und versuche mit einem Thread und meiner Hauptapplikation in dieses reinzuschreiben (logging). Bei der Programmierung war mir also klar, dass ich eine Critical Section verwenden müsste.
Dies hab ich auch gemacht, jedoch stürzt das Programm einfach ab, wenn beide ins RichEdit reinschreiben wollen. Ich kanns auch nicht debuggen, da es dann nicht abstürzt und richtig läuft.

Ich habe jetzt schon einiges probiert und festgestellt, dass sobald irgendetwas mit dem rtfOutputWindow (RichEdit) in der Critical Section gemacht wird, es zum absturz kommt. Kommentiere ich diese aus stürzt es nicht ab (hab dann aber auch nicht die gewünschte Funktion).

Hat irgendjemand eine Idee??? Vielen Dank schonmal

hier mal der Code:

Delphi-Quellcode:
procedure TFrmApplication.PutTextToOutputWindow(Text: String; Color: TColor);
var
  Zeit:String;
Begin
  if CriticalSection <> nil then
  begin
    CriticalSection.Enter; // Critical Section gestartet
    /////////////////////////////////////////////////////
    rtfOutputWindow.SelAttributes.Color := Color;
    //Timestamp einfügen
    DateTimeToString(Zeit, 'hh:nn:ss:zzz', Now);
    Text := Zeit + ' ' + Text;
    rtfOutputWindow.SelStart := rtfOutputWindow.GetTextLen;
    rtfOutputWindow.Lines.Add(Text);
    SendMessage(rtfOutputWindow.Handle, EM_LINESCROLL , 0, 1);
    /////////////////////////////////////////////////////
    CriticalSection.Leave; // Critical Section beendet
  end
  else
    Assert(FALSE,'CriticalSection = nil');
end;

himitsu 6. Jun 2008 07:45

Re: Problem mit Critical Section
 
mit CriticalSection blockierst du nur den gleichzeitigen Zugriff innerhalb der Funktion.

Aber es ist wichtiger auch die Zugriffe der VCL zu blockieren ... schau mal nach Hier im Forum suchenSynchronize / Hier im Forum suchenThread Synchronize.

DoktorD 6. Jun 2008 07:47

Re: Problem mit Critical Section
 
Mhhh. Verstehe ich irgendwie nicht. Ich greife ja auch nur innerhalb dieser Funktion auf das RichEdit zu. Diese Funkion wird vom beiden Threads aufgerufen.

Kannst du mirs vielleicht ein bisschen deutlicher erklären?

Danke

SirThornberry 6. Jun 2008 07:54

Re: Problem mit Critical Section
 
Es kommt zu "tollen" fehlern wenn du von einem anderen Thread (als dem Hauptthread) auf VCL-Object zugreifst. Es ist dabei unabhängig ob diese durch eine CriticalSection abgesichert sind. Du solltest sicherstellen das Zugriffe auf dein RichEdit ausschließlich vom Hauptthread aus erfolgen. Und um das zu erreichen kann im im TThread die Methode syncronize benutzen.

himitsu 6. Jun 2008 07:54

Re: Problem mit Critical Section
 
Damit das RichEdit verwaltet und angezeigt werden kann, greift die VCL (ohne Beachtung deiner CriticalSection) auch noch darauf zu
und nicht nur deine beiden Threads (mit dieser Funktion/CriticalSection).

Mit Synchronize (TThread) wird die an Synchronize übergebene Prozedur sozusagen im Kontext des Hauptthreads ausgeführt ... heißt es kann nur noch Einwas (über den Hauptthread) zur gleichen Zeit zugreifen.

DoktorD 6. Jun 2008 07:59

Re: Problem mit Critical Section
 
Aha. Jetzt hab ichs verstanden.

Schickt das, wenn ich das dann so mache? Mit DebugString wird die oben gezeigte Funktion aufgerufen die dann ins RichEdit schreibt.

Delphi-Quellcode:
procedure CThread1.Execute;
begin
  inherited;

  while not Terminated do
  begin
    Synchronize(LogString);
  end;
end;

procedure CThread1.LogString;
begin
  DebugString('Thread 1.1');
  DebugString('Thread 1.2');
  DebugString('Thread 1.3');
end;

DoktorD 6. Jun 2008 10:02

Re: Problem mit Critical Section
 
Also. Ich hatte eben den Effekt, dass ich wenn ich im Thread mit Synchronize arbeite, dass mein Programm abstürzt, sobald es in die Critical Section kommt (Enter).
Die Critical Section habe ich dann entfernt. Nun habe ich aber nicht mehr die Funktion des Threads wie vorher.
D.h. wenn über das Hauptfenster ein Modales Fenster geöffnet wird, stoppt der Thread und fängt erst wieder an, wenn ich das Fenster wieder schließe.

Warum ist das mit Synchronize so? Das ist doch gerade der Vorteil von Threads, das ich etwas parallel laufen lassen kann, oder?

sirius 6. Jun 2008 10:13

Re: Problem mit Critical Section
 
Synchronize interessiert sich nicht für modal, es reagiert wie gewöhnlich. Dein Fehler muss woanders liegen


EDit: 2000 :firejump:

himitsu 8. Jun 2008 17:09

Re: Problem mit Critical Section
 
Synchronize wartet mit der Ausführung der Funktion, bis der Hauptthread zeit für deren Ausführung hat ... heißt, wenn der Hauptthread grad etwas macht, dann stoppt sozusagen der aufrufende Thread.

aber eigentlich ollte der Haupthtread eigentlich nicht viel zu tun haben,
oder fürhrst du dort irgendwelche "aufwendigeren" Operationen aus?


Alle Zeitangaben in WEZ +1. Es ist jetzt 16:33 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