Vielen Dank für alle Beiträge! Ich muß zugeben: Jeder hat in etwa das geschrieben, was ich von ihm erwartet habe.
Zuerst muß ich
Stevie Recht geben: Diese Probleme entstehen, wenn man eine untypisierte GC Sprache nach Delphi umsetzen möchte... Aber bei diesem Ansatz will ich bleiben und deshalb soll und muß aller Verwaltungsaufwand für den Anwender (des Frameworks) hinter den Kulissen bleiben. Der Programmierer soll sich voll und ganz auf die Umsetzung seiner Ideen konzentrieren können. Deshalb sollen auch keine zusätzlichen Aufrufe notwendig sein.
@
Furtbichler:
Vielen Dank für Deine Antwort!
Deine Sorge besteht darin, daß irgendwelche fremden Programmteile Deinem eigenen Code "dazwischen pfuschen". Dieses Gefühl ist bei Multithreadanwendungen vollkommen berechtigt. Leider zeugt das aber auch davon, daß Du Dich - höchstwahrscheinlich - kein einziges mal mit dem von mir angesprochenen Framework beschäftigt hat. Das soll kein Vorwurf sein - schließlich ist das auch keine Pflicht. Hättest Du das aber gemacht, wüßtest Du, das es gar nicht threadsave sein muß, da die JScript-Engine von Microsoft nicht multithreadsicher ist.
Spontan auftretende
nil-Zeiger der Art
Delphi-Quellcode:
if assigned(FMyMarker) then
begin
//<- ist hier plötzlich weg
FMyMarker. ...;
end;
können also gar nicht auftreten. Auch alle asynchronen JScript-Callbacks laufen im Context des Hauptthreads.
Wie threadsicher ein Interface ist, hängt von seiner
Implementation ab, nicht von seiner
Definition. Wie das
INotify.Free umgesetzt wird - ob als direkte, unmittelbare Freigabe in Singlethread-Anwendungen oder "angemeldet" und zeitlich verzögert-, hängt ganz von den Erfordernissen ab.
Ich gebe Dir aber vollkommen Recht: In Multithreadanwendungen muß ein höherer Verwaltungsaufwand betrieben werden, als in einem Programm, in dem nur ein Thread (in der Regel der Hauptthread) auf den Datenbestand zugreift. Das vorgestelle Interface wurde von mir primär für das Framework entworfen, um die automatisch Speicherverwaltung von Delphi über Referenzzähler nutzen zu können ohne die Nachteile eines
TInterfacedObject's. Für eine darüber hinausgehende Anwendung sind ganz bestimmt noch weitere Aspekte zu berücksichtigen.
@
himitsu:
Das vorgestellte Interface ist von
IInterface abgeleitet. Deshalb beinhaltet das implementierende Objekt
INotifyObjekt auch eine Referenzzählung mit
_AddRef und
_Release. Mir geht es aber darum, ein referenzgezähltes Objekt explizit freigeben zu können, ohne daß es zu Zugriffsverletzungen über andere, parallel existierende Referenzen kommt.
Die Registrierung/Deregistrierung lokaler (Interface-)Variablen auf dem Stack erfolgt automatisch. Das bedeutet, daß nach Verlassen der Methode die Referenz wieder entfernt wird. Es kann also nicht vorkommen,
Delphi-Quellcode:
type
TForm1 = class([...])
[...]
private
FMyNotify: INotify;
end;
procedure TForm1.Button1Click(Sender: TObject);
var
o: INotify;
begin
o:=TNotifyObject.Create;
FMyNotify:=o;
end;
procedure TForm1.Button2Click(Sender: TObject);
begin
FMyNotify:=nil;
end;
daß jetzt, bei Freigabe des Objektes in
Button2Click, die (Stack-)Variable "o" auf
nil gesetzt wird. "o" wird bei der Zuweisung in
Button1Click registriert und nach Beendigung der Methode vom Compiler auf
nil gesetzt sowie über
INotify.RemoveRef(o) abgemeldet. Alles ganz einfach und vollautomatisch. Ich will das mal "managed Reference" nennen.
Anders sieht es natürlich bei einer expliziten Registrierung einer Variablen über
AddRef() aus - also einer "unmanaged Reference". Hier muß natürlich dafür gesorgt werden, daß es nicht zu Zugriffsverletzungen kommt. Ich würde es einmal vergleichen mit dem Aufruf eines
xxx.Lock: Wird anschließend das
xxx.Unlock vergessen, gibt es logischerweise Probleme. Das hat aber nichts mit Fehlern im Konzept, sondern mit der Vergeßlichkeit des Programmieres zu tun. Das von mir vorgestelle Interface kann die Arbeit wesentlich erleichtern - ist aber keine Lizenz zum Abschalten des eigenen Gehirns.
Meine Umsetztung funktioniert in den bisherigen Tests sehr zuverlässig.
@
Patito:
Hast Du auch irgend etwas Sachliches zu dem Thema beitragen oder beschränkst Du Dich immer auf platte Statements?