Yes, the BeginUpdate call Lock internally, and the EndUpdate call Unlock. The same critical section. Just one critical section per object.
Yes, my Change event is completely asynchronous, similar to the fmx messaging system (subscribe / unsubscribe), but it uses X threads to send these messages from one thread to another.
I don't like the term "big risk" or "low risk" of deadlock. A good design has to be done with the chance of zero deadlock, locking the object just to copy the data to the local var of the thread or else locking only to write local var of the thread in the object (without executing anything inside locking).
Example:
procedure TipThread.Execute
var
LName: string;
LId: Cardinal;
begin
// Read copying to local var
LUser.Lock;
try
LName := LUser.Name;
LId := LUser.Id;
finally
LUser.Unlock;
end;
// Run your code...
// Write from local var
LUser.BeginUpdate;
try
LUser.Name := LName;
LUser.Id := LId;
finally
LUser.EndUpdate;
end;
end;
This will never cause a deadlock.