2016-06-07 1 views
1

J'ai un problème lorsque je synchronise TIdSync dans Delphi 7 (avec le dernier Indy) à l'intérieur de plusieurs threads en même temps, il exécute la même instance TIdSync plusieurs fois.
Voici un code simple. TIdSync est créé et appelé dans mon TThread. Il devrait passer et montrer son handle pour ce cas. Mais j'ai une liste avec les mêmes poignées dans le mémo. Cela fonctionne correctement dans Delphi 2010+ (probablement parce qu'il supporte les méthodes anonymes). Je ne sais pas si je comprends comment TIdSync devrait fonctionner, si je l'utilise mal ou s'il y a un bug ou une condition de concurrence?TIdSync se synchronise incorrectement

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; 

j'obtenir la liste comme ça dans Delph 7 avec les mêmes hadnles (donc il ne passe pas les valeurs de droite)
38972948: 38972948
38970260: 38970260
38970260: 38970260
38970260: 38970260
. ..

et Delphi 2010, il est correct
39063248: 39063248
39063296: 39 063296
39063312: 39063312
39063328: 39063328

Il est un problème tout à fait désagréable que vous voyez. Tout indice apprécié.

+1

doit avoir' ensemble FreeOnTerminate' à true pour éviter les objets filetés qui fuient. 'Resume' est dangereux à utiliser (et obsolète depuis Delphi-XE). –

+0

Je ne peux pas voir de mauvaise conduite. Qu'est-ce qui te fait ressentir ça? Bien que s'il y aurait un problème votre code n'est pas le meilleur pour montrer ce problème. En fait vous voyez ici le comportement différent du gestionnaire de mémoire D7 vs. D2010: o) –

+0

@LURD: Vrai, FreeOnTerminate devrait être là mais ne cause pas le problème. Juste un cas de test. La reprise est correcte - c'est Delphi 7. – smooty86

Répondre

1

S'il vous plaît vérifier à nouveau avec un petit changement pour verrouiller la réutilisation des adresses mémoire:

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; 

Comme vous le verrez, il n'y a pas de problème du tout `TTestThread`

+0

Cela fonctionne de la même manière. L'avez-vous testé en D7 et cela a fonctionné correctement? – smooty86

+0

Avez-vous libéré le fil à tout moment? –

+0

J'ai essayé les deux avec FreeOnTerminate et sans libérer. – smooty86