Random Thoughts on the Passing Scene #38
20 Oct
- Practically everyone here uses QualityCentral every day. QC is vital to the success of our products, but QC requires excellent community participation to be fully useful. Pursuant to that, David Dean has out a call for QC Sysops. (As an aside, David Dean is a truly outstanding addition to the CodeGear team, and first came to our attention via his great work in QC.) So if you are looking for a way to contribute to and participate in the community, this is a good opportunity. Give it a shot.
- Danny Thorpe has a new job and a new blog.
- A lot of customers ask me: "When are we going to have a thread-safe VCL?" and my initial response is usually this: "What do you mean by a ‘thread-safe VCL’?" I ask this because Win32 user interface work is inherently single-threaded. (Tip to Craig Stuntz for the link)
- In the newsgroups, Joe Hendricks pointed out a real "blast from the past" — the SWAG archives. Anyone remember that? Looks like Jim McKeeth was kind enough to turn it all into HTML.
- Want to join the R&D Team here at CodeGear? We are looking for a database guy.


> A lot of customers ask me: "When are we going to have a
> thread-safe VCL?" and my initial response is usually this:
> "What do you mean by a ‘thread-safe VCL’?"
I don’t know what "a lot of customers" mean by this, but what *I* would like is the ability to call VCL functions from a secondary thread without the need for Synchronize, and the ability for a secondary thread to hook into a VCL event.
It can be done - sort of - by using class-scope global variables (f.ex. if you want to update a TLabel’s caption, I usually code it something like this:
PROCEDURE SetLabelCaption(L : TLabel ; Caption : STRING);
BEGIN
ClassGlobalStringVar:=Caption;
ClassGlobalLabelVar:=L;
Synchronize(SetLabelFunc)
END;
PROCEDURE SetLabelFunc;
BEGIN
ClassGlobalLabelVar.Caption:=ClassGlobalStringVar
END;
but it would be much nicer to be able to just do
MainForm.Label.Caption:=’Progress: ‘+IntToStr(Percent)+’%’
So, that’s what *I* mean by "thread-safe VCL"…
October 21st, 2007 at 12:27 amHi Nick,
not to be nitpicking:
"(As an aside, David Dean is an outstanding edition to the CodeGear team, and first came to our attention via his great work in QC.)"
You probably meant "addition", do you?
twm
October 21st, 2007 at 2:11 amThomas –
Indeed I do. Corrected.
Nick
October 21st, 2007 at 4:12 amKeld –
The problem with what you want is that it would be mean putting locks around /every/ VCL property call, and I’m sure you can imagine what that would do to performance.
Nick
October 21st, 2007 at 4:23 amSome people probably mean "thread-safe VCL" to mean "let me be lazy and not worry about thread synchronization", which isn’t realistic (unless you want to drastically slow down the people who actually know what they’re doing).
That’s not what I’m looking for. I would just like to be able to create GUI on multiple threads. The VCL currently only allows you to create GUI on the primary thread; I want to be able to spin up secondary threads and create GUI from there. Trivial in WinForms, impossible in VCL (because there’s one shared TApplication, one shared TScreen, etc., and they don’t have any critical sections).
October 21st, 2007 at 4:28 amBTW, I’m mainly interested in being able to create new *forms* from threads. I’m not so interested in creating a frame from a thread and then parenting it to a form from another thread. (I’m not sure Windows even allows that.)
Ideally, I’d like to be able to create those forms with a PopupOwner from a different thread.
October 21st, 2007 at 4:37 amDo you *really* need to put locks on *every* call? Couldn’t it be done by some compiler magic (ie. still do it with "Synchronize", but without me needing to know about it)?
Someling like:
PROCEDURE SetLabelCaption(L : TLabel ; Caption : STRING); Threaded;
BEGIN
L.Caption:=Caption
END;
and if the compiler could even detect it within a TThread descendant automatically (for example by having a Threaded clause to classes that would activate the compiler magic) so that in any method within the class that touches non-threaded classes, it would do a synchronize behind-the-scenes.
I do not object to the use of "Synchronize", only to the need for me to know about it :-).
October 21st, 2007 at 5:27 amKeld,
To call VCL functions from a secondary thread without calling Synchronize, use QueueUserAPC. For a complete example, see my comment on Allen’s blog entry on Spot the deadlock.
October 21st, 2007 at 6:02 amThread safe VCL? Well, for example to be able to draw text on a TBitmap.Canvas in a thread:
with TBitmap.Create do
begin
Canvas.Textout(’test’)
Free;
end;
Above example is not possible, because canvas is not threadsafe. But it is not visible at all!
October 21st, 2007 at 10:54 pmChee - your example still needs class-scope global variables to work, and this is what I don’t like (and want to avoid).
If it is implemented as compiler magic, the class-scope global variables will not be visible to or accessible by other code in the class, even though behind the scenes it’ll still be implemented as such.
That’s what I would like to achieve - a transparent way of updating UI elements from a secondary thread. I should be allowed to just write MainForm.ProgressLabel.Caption:=’…’ and the compiler should wrap this into a synchronize call without me knowing about it.
That way we could *appear* to have thread-safe VCL, even though it isn’t *really* thread-safe (just like compiler magic auto-boxing in .NET allows you to type cast away between managed and unmanaged types in Delphi.NET, if I understand it correctly).
October 21st, 2007 at 11:41 pmFWIW, Michael Beck uploaded the SWAG archive to CodeCentral back in the first year CodeCentral was made public. That’s why he has so many entries in CodeCentral
However, it’s nice to have a distinctly separate HTML archive of them, too.
October 22nd, 2007 at 10:48 am