![]() |
Critical Section um globale Methode?
Ich habe eine Methode, die in einer Unit mit global verfügbare Klassen und Methoden liegt.
Die Methode behandelt Clipboard-Operationen. Hierbei kann es zu Konflikten und folgender Fehlermeldung kommen: "Zwischenablage Zugriff verweigert kann nicht geöffnet werden" Nach meiner Recherche kommt es zu dieser Meldung, wenn zwischen Clipboard.Open und Clipboard.Close ein weiterer Zugriff auf die Zwischenablage erfolgt. Als Lösung viel mir als erstes ein, dass der Code von Clipboard.Open und Clipboard.Close eigentlich ein kritischer Abschnitt ist. Leider kenne ich mich mit der Implementierung von critical sections unter Delphi nicht so gut aus. Wie ließe sich das in diesem Kontext implementieren? Oder gibt es andere Lösungen für das Problem? Hier mal etwa Code:
Delphi-Quellcode:
Wäre es zb. möglich eine Unit-globale Variable vom Typ CriticalSection zu deklarieren und diese dann in SaveClipboard zu verwenden?
Unit GlobalStuff;
... function SaveClipboard : TList; ... function SaveClipboard : TList; begin ... ClipBoard.Open; ... ClipBoard.Close; ... end; |
AW: Critical Section um globale Methode?
Als erstes fiele mir auf jeden Fall ein Das Open/Close erst einmal mit einem
Delphi-Quellcode:
abzusichern ;-)
try..finally
Ein kritischer Abschnitt oder ähnliche Sicherungsmechanismen helfen dir eigentlich nur wenn du genau diese Methode aus verschiedenen Threads gleichzeitig aufrufen willst. Wenn dir da irgendein anderer Mechanismus für den Zwischenablagen-Zugriff reinfunkt (z.B. durch Drittanbieter-Komponenten oder ähnliches) hilft dir das auch nichts. |
AW: Critical Section um globale Methode?
Das stimmt. Die Vermutung besteht aber, dass verschiedene Threads unseres Programmes auf die Methode zugreifen. Das ist theoretisch möglich, da die Methode wie gesagt global verfügbar ist. Ob das aber wirklich so passiert, kann ich nicht sagen. Ein Kunde hat das Problem berichtet, reproduziert bekomme ich es nicht :wink:
Daher wäre ohnehin jede Lösung, die ich einbaue, ein Schuss ins Blaue. |
AW: Critical Section um globale Methode?
Soweit wir noch nicht bei Science Fiction sind sollte dein Programm auch nur das tun was im Quelltext steht. Schau doch einfach an welchen Stellen im Code die Methode aufgerufen wird und nicht "theoretisch könnte das sein" ;-)
Critical Sections sind einfach: Du erzeugst dir einmalig so ein Objekt, und immer um einen Abschnitt zu sperren sagst du einmal
Delphi-Quellcode:
und wenn du fertig bist
Acquire()
Delphi-Quellcode:
Release()
![]()
Delphi-Quellcode:
uses
System.SyncObjs; var criticalSection: TSynchroObj; procedure funWithClipboard(); begin criticalSection.Acquire(); try ClipBoard.Open(); try // (...) finally ClipBoard.Close(); end; finally criticalSection.Release(); end; end; PS: Software die das Haus verlässt braucht unbedingt vernünftiges Exception-Logging sodass du direkt den kompletten Aufruf-Stack bekommst. Wenn die einzige Info nur ein kurzer Text auf einer Messagebox ist wird man echt nicht glücklich. |
AW: Critical Section um globale Methode?
Zitat:
Zitat:
Zitat:
|
AW: Critical Section um globale Methode?
Viel einfacher:
Delphi-Quellcode:
Schneller als eine Critical Section, genau auf das Objekt bezogen und ohne zusätzliche Initialisierung usw.
TMonitor.Enter(ClipBoard);
try ... finally TMonitor.Exit(ClipBoard); end; |
AW: Critical Section um globale Methode?
Zitat:
![]() Meines Wissens nach versucht die Windows Implementation der Critical Section mitlerweile auch erstmal ein SpinLock, bevor es dann den teuren Context-Switch in den Kernel gibt. Sollte also nun sogar noch performanter sein. |
AW: Critical Section um globale Methode?
In deinem Link steht doch genau die Antwort auf die Berichte über die schlechte Performance. Seit XE5 ist das behoben und schneller als eine CS.
Hier auch nochmal der Link: ![]() |
AW: Critical Section um globale Methode?
Zitat:
![]() |
AW: Critical Section um globale Methode?
Müssen Clipboard Operationen nicht auch im Mainthread ablaufen? Dann wäre noch ein Synchronize nötig und könnte vielleicht auch schon alleine helfen.
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 04:12 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz