2009-04-01 10 views
2

Angenommen, eine Multi-Threaded-Umgebung und eine (richtig synchronisiert) Klasse, die ein bestimmtes Verfahren hatVergleich Funktion und Multithreading

procedure SortKeyList (KeyList : TList <Integer>; Inverted : Boolean); 

, das eine Liste von Schlüsseln nimmt und sortiert sie. Das Verfahren nutzt die RTL quicksort Implementierung TList.Sort:

KeyList.Sort (TComparer <Integer>.Construct (CompareKeys)) 

Nun zum Problem: CompareKeys hat einige Mitglieder der Klasse, um den Zugriff auf die Liste (das ist der springende Punkt bei dieser Klasse) zu sortieren. Aber das RTL erfordert CompareKeys, um eine normale Funktion zu sein. Wie kann ich Daten aus dem Objekt thread-sicher an die CompareKeys-Funktion übergeben? Offensichtlich ist die Verwendung globaler Austauschvariablen keine Option, da sie in keiner Weise Thread-sicher ist.

Irgendwelche Ideen dazu?

Antwort

4

Die Tatsache, dass Sie CompareKeys-TComparer.Construct vorbei sind bedeutet, dass CompareKeysnicht haben eine normale Funktion sein. Delphi 2009 eingeführt Methodenreferenzen, die sich auf normale Funktionen, Methoden und anonyme Methoden beziehen können. Ich nehme an, dass TComparer.Construct eine Methodenreferenz außerhalb der normalen Funktion erstellt, die Sie ihr geben. (Ich bin nicht sicher, warum, obwohl, ich dachte, der Compiler, dass die Umwandlung automatisch tat.)

Angenommen, Sie haben eine Drei-Argument-Funktion, die eine Liste und die beiden Elemente erhält zum Vergleich:

function CompareKeys(List: TList<Integer>; Item1, Item2: Integer): Integer; 

Sie sollten in der Lage sein, eine anonyme Methode wie folgt zu übergeben:

KeyList.Sort(function(Item1, Item2: Integer): Integer; 
    begin 
    Result := CompareKeys(KeyList, Item1, Item2); 
    end); 
+0

+1 große Antwort. Anonyme Methoden mit ihrer Fähigkeit, auf den aufrufenden Kontext zuzugreifen, geben mir genau das, was ich brauche! Hab nicht daran gedacht! Vielen Dank! – jpfollenius

2

Vielleicht könnten Sie eine threadvar (lokale Threadvariable) verwenden, um einen Verweis auf Ihre Instanz zu speichern, auf die dann von der CompareKeys-Funktion zugegriffen werden kann (weisen Sie die Threadvariable kurz vor dem Aufruf von Sort zu).

+0

+1 danke, das sollte funktionieren! – jpfollenius