Page 1 of 1

CodeSite and SendMessage sync

PostPosted: Tue Feb 14, 2017 2:57 am
by IvanovAlex
Delphi XE2 + CodeSiteExpress
Can I use CodeSite in this case (using SendMessage for Sync threads) correctly ?


TTestThread = class (TTHread)
...


var
A : array [0..100] of TTestThread;

function SyncWithMainThread (SF : TSyncFunction; Param : Pointer) : Integer;
var
PM : ^TMethod;
begin
Result := -1;
if not Assigned(frmWMSync) then Exit;
New (PM);
Move(SF,PM^,8);
SendMessage(frmWMSync.Handle,WM_USER+1,Integer(Param),Integer(PM));
Dispose (PM);
end;

procedure TForm1.btn1Click(Sender: TObject);
var
i : Integer;
begin
CodeSite.Clear;
CodeSiteManager.SetCurrentThreadName('Main');
mmo1.Lines.Clear;
frmWMSync := TfrmWMSync.Create(nil);
CC := 0;
for I := 0 to High(A) do
begin
A[i] := TTestThread.Create (true);
A[i].Idx := i;
A[i].Start;
end;
end;


procedure TTestThread.Execute;
begin
CodeSiteManager.SetCurrentThreadName('Thread ' + IntToStr(Idx));
FreeOnTerminate := false;
while (not Terminated) do
begin
SyncWithMainThread (Sync2,@Idx); // [2]
// Synchronize(SyncLocal); // [3]
break;
end;
end;

function TTestThread.Sync2(Param: Pointer): Integer;
begin
form1.mmo1.Lines.Add ('Sync enter ------->> ' + IntToStr(Idx));
CC := CC + 1;
//CodeSite.Send (PChar('Sync enter ------->> ' + IntToStr(Idx))); // [1]
if (CC <> 1) then
form1.mmo1.Lines.Add ('!!!!CC ' + IntToStr(CC));
Result := 0;
form1.mmo1.Lines.Add ('Sync done <<<------- ' + IntToStr(Idx));
CC := CC - 1;
Result := Idx;
end;


This code - is Ok.
In Memo I see
Sync enter ------->> 0
Sync done <<<------- 0
Sync enter ------->> 1
Sync done <<<------- 1
...

If uncomment [1]

In Memo I see
Sync enter ------->> 0
Sync enter ------->> 1
Sync enter ------->> 2
Sync done <<<-------0
...

i.e. code
CodeSite.Send (PChar('Sync enter ------->> ' + IntToStr(Idx))); // [1]
switch threads

And it's a big problem if in Sync2 method i try to access to not threadsave object.

If comment [2], and uncomment [3] (use Synchronize for Sync) - all is Ok again.

Re: CodeSite and SendMessage sync

PostPosted: Wed Feb 15, 2017 2:22 am
by Raize Support
I'm not really sure what you are trying to accomplish with this code. From what I can tell, there is nothing that ensures that the Sync2 calls are executed sequentially. The CodeSite.Send call does much more work than any of the other statements in that method and as a result, the processor gives some time to another thread. However, all of the statements within Sync2 (including the CodeSite.Send call) should all be in the context of the main thread.

Ray