Announcement

Collapse
No announcement yet.

Synchronize funktioniert nicht!?

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

  • Synchronize funktioniert nicht!?

    Hallo.
    Ich habe eine Applikation geschrieben die u.a. viele Bildbearbeitungen macht. Dafür gibt es Progressbars und das Ganze soll in einem Hintergrundthread ablaufen. Um die Position der Progressbar zu setzen benutze ich eine Variable:
    Code:
    strict private
      BarPos : Integer;
    und eine Methode:
    Code:
    strict private
      procedure SetBarPos;
    ...
    Code:
    procedure TMyThread.SetBarPos;
    begin
      VisuForm.Bar.Position := BarPos;
    end;
    Diese Methode wird NUR über
    Code:
    Synchronize(SetBarPos);
    aufgerufen. Und dennoch kommt es zu Fehlern. Wenn ich die Zuweisung auskommentiere und durch etwas anderes (z.B.
    Code:
    Beep;
    ) ersetze, dann passiert nichts (das Programm läuft normal ab).

    Ich habe auch schon CriticalSections und VisuForm.Canvas.Lock/Unlock vergeblich ausprobiert. Der Fehler tritt nur auf Multicore-Systemen auf.

    Diese ProgressBars werden von dem DWM gerendert. Dies scheint auch in einem separaten Thread zu geschehen, da das Lauflicht (unter Vista) bei Stillstand des Haputthreads weiterläuft.

    Gibt es dafür eine Lösung? Ist das ein Bug? Oder mach ich da was falsch?
    Zuletzt editiert von X-odus; 11.04.2008, 12:00.

  • #2
    Problem gelöst

    Ich rufe in dem Thread diverse Win API Methoden wie BitBlt und PlgBlt auf. Diese verursachen zeitversetzt die Probleme. Ich habe zwar keine Ahnung, warum die Aufrufe schief gehen, aber mit einem Canvas.Lock davor und einem Canvas.Unlock dahinter funktionierts.

    Das TBitmap, das den Canvas enthält wird (zumindest von meinem Code) ausschließlich innerhalb des Threads benutzt. Wenn mir jemand erklären kann, warum der Canvas gelockt werden muss, soll er sich nicht zurückhalten. :-)

    Comment


    • #3
      Das ist eigentlich ganz einfach. TCanvas verwaltet diverse Pools für z.B. TPen und TBrush usw. um eine effektive Nutzung der Ressourcen zu erreichen. D.h. diese Objekte werden mehrfach verwendet, sind aber selbst nicht threadsafe. Entweder Du arbeitest komplett direkt mit der GDI-Schnittstelle (also alle Grafikobjekte selbst erzeugen) oder Du must eben diese Poolverwendung mit Canvas.Lock mal kurz sperren.

      Comment


      • #4
        Aha - ok.
        Danke vielmals für die Aufklärung!

        mfG.

        Comment

        Working...
        X