Delphi-PRAXiS
Seite 1 von 4  1 23     Letzte »    

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Algorithmen, Datenstrukturen und Klassendesign (https://www.delphipraxis.net/78-algorithmen-datenstrukturen-und-klassendesign/)
-   -   Critical Section um globale Methode? (https://www.delphipraxis.net/192619-critical-section-um-globale-methode.html)

Rabenrecht 5. Mai 2017 09:02

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:
Unit GlobalStuff;
...
function SaveClipboard : TList;
...
function SaveClipboard : TList;
begin
  ...
  ClipBoard.Open;
  ...
  ClipBoard.Close;
  ...
end;
Wäre es zb. möglich eine Unit-globale Variable vom Typ CriticalSection zu deklarieren und diese dann in SaveClipboard zu verwenden?

Der schöne Günther 5. Mai 2017 09:28

AW: Critical Section um globale Methode?
 
Als erstes fiele mir auf jeden Fall ein Das Open/Close erst einmal mit einem
Delphi-Quellcode:
try..finally
abzusichern ;-)

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.

Rabenrecht 5. Mai 2017 09:52

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.

Der schöne Günther 5. Mai 2017 10:10

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:
Acquire()
und wenn du fertig bist
Delphi-Quellcode:
Release()
http://docwiki.embarcadero.com/RADSt...che_Abschnitte

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.

Rabenrecht 5. Mai 2017 11:21

AW: Critical Section um globale Methode?
 
Zitat:

Zitat von Der schöne Günther (Beitrag 1370299)
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" ;-)

Die Codebasis ist über mehr als 20 Jahre entstanden, das Programm entsprechend groß und teilweise unübersichtlich. So einfach ist das leider nicht.

Zitat:

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.
Haben wir. Bringt uns hier nur nichts, da ich das Problem bisher nicht reproduzieren kann. Ich muss mit dem Arbeiten, was der Kunde mitteilt.

Zitat:

Critical Sections sind einfach: Du erzeugst dir einmalig so ein Objekt, und immer um einen Abschnitt zu sperren sagst du einmal
Delphi-Quellcode:
Acquire()
und wenn du fertig bist
Delphi-Quellcode:
Release()
http://docwiki.embarcadero.com/RADSt...che_Abschnitte

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;

Das werde ich mal versuchen, danke :)

jaenicke 5. Mai 2017 13:42

AW: Critical Section um globale Methode?
 
Viel einfacher:
Delphi-Quellcode:
TMonitor.Enter(ClipBoard);
try
  ...
finally
  TMonitor.Exit(ClipBoard);
end;
Schneller als eine Critical Section, genau auf das Objekt bezogen und ohne zusätzliche Initialisierung usw.

Zacherl 5. Mai 2017 14:26

AW: Critical Section um globale Methode?
 
Zitat:

Zitat von jaenicke (Beitrag 1370323)
Schneller als eine Critical Section

Sofern sich da nichts geändert hat, dann leider nicht. Siehe z.b.:
https://www.delphitools.info/2013/06...iticalsection/

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.

jaenicke 5. Mai 2017 14:33

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:
https://community.embarcadero.com/bl...-monitor-38952

TiGü 5. Mai 2017 14:35

AW: Critical Section um globale Methode?
 
Zitat:

Zitat von Zacherl (Beitrag 1370332)
Zitat:

Zitat von jaenicke (Beitrag 1370323)
Schneller als eine Critical Section

Sofern sich da nichts geändert hat, dann leider nicht. Siehe z.b.:
https://www.delphitools.info/2013/06...iticalsection/

Laut diesem Blogpost ist das seit XE5 gefixt:
http://blog.synopse.info/post/2016/0...d-applications

freimatz 11. Mai 2017 09:29

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 16:26 Uhr.
Seite 1 von 4  1 23     Letzte »    

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