2016-06-07 30 views
1

Ich habe ein Problem, dass wenn ich TIdSync in Delphi 7 (mit dem neuesten Indy) in mehreren Threads gleichzeitig synchronisiert, führt es die gleiche TIdSync-Instanz mehrmals.
Hier ist ein einfacher Code. TIdSync wird in meinem TThread erstellt und aufgerufen. Es sollte passen und seinen Griff für diesen Fall zeigen. Aber ich bekomme eine Liste mit den gleichen Handles im Memo. Es funktioniert korrekt in Delphi 2010+ (wahrscheinlich weil es anonyme Methoden unterstützt).TIdSync synchronisiert falsch

Ich bin mir nicht sicher, ob ich verstehe, wie TIdSync funktionieren sollte, verwenden Sie es falsch oder gibt es einen Fehler oder eine Race Condition?

type 
    TMySync = class(TIdSync) 
    protected 
    procedure DoSynchronize; override; 
    public 
    FID: Integer; 
    end; 

type 
    TTestThread = class(TThread) 
    private 
    { Private declarations } 
    protected 
    procedure Execute; override; 
    end; 

procedure TTestThread.Execute; 
var 
    sync: TMySync; 
begin 
    // synchronize some data 
    sync:=TMySync.Create; 
    try 
    sync.FID:=Integer(sync); // this handle 
    sync.Synchronize; 
    finally 
    sync.Free; 
    end; 
end; 

procedure TMySync.DoSynchronize; 
begin 
    // show handle and stored handle 
    Form1.Memo1.Lines.Add(IntToStr(Integer(Self))+' : '+IntToStr(FID)); 
end; 

procedure TForm1.Button2Click(Sender: TObject); 
var 
    i: Integer; 
begin 
    // execute multiple threads 
    for i:=0 to 10 do 
    with TTestThread.Create(True) do 
     Resume; 
end; 

ich Liste wie diese in Delph 7 mit gleichen hadnles (so es nicht richtig Werte übertragen wird)
38.972.948: 38972948
38970260: 38970260
38970260: 38970260
38970260: 38970260
. ..

und in Delphi 2010 ist es richtig
39.063.248: 39063248
39063296: 39 063296
39063312: 39063312
39063328: 39063328

Es ist ziemlich unangenehmes Problem, wie Sie sehen. Jeder Hinweis geschätzt.

+1

'TTestThread' muss' haben FreeOnTerminate' Set zu true, um undichte Objekte zu vermeiden. "Fortsetzen" ist unsicher zu verwenden (und seit Delphi-XE veraltet). –

+0

Ich kann kein Fehlverhalten sehen. Wie fühlst du dich so? Obwohl, wenn es ein Problem geben würde, ist Ihr Code nicht das beste, um dieses Problem zu zeigen. Tatsächlich sieht man hier das unterschiedliche Verhalten vom Speichermanager D7 vs. D2010: o) –

+0

@LURD: True, FreeOnTerminate sollte da sein aber verursacht nicht das Problem. Nur ein Testfall. Resume ist korrekt - es ist Delphi 7. – smooty86

Antwort

1

Bitte versuchen Sie es mit einer kleinen Änderung, die Wiederverwendung von Speicheradressen zu sperren:

type 
    TTestThread = class(TThread) 
    private 
    sync: TMySync; 
    protected 
    procedure Execute; override; 
    public 
    destructor Destroy; override; 
    end; 

{ TTestThread } 

destructor TTestThread.Destroy; 
begin 
    inherited; 
    sync.Free; 
end; 

procedure TTestThread.Execute; 
begin 
    inherited; 
    sync := TMySync.Create; 
    sync.Id := Integer(sync); 
    sync.Synchronize; 
end; 

Wie Sie sehen, gibt es kein Problem bei allen

+0

Es funktioniert genauso. Hast du es in D7 getestet und es hat richtig funktioniert? – smooty86

+0

Haben Sie den Thread jederzeit freigegeben? –

+0

Ich habe versucht sowohl mit FreeOnTerminate als auch ohne zu befreien. – smooty86