<?xml version="1.0" encoding="UTF-8"?><!-- generator="wordpress/wordpress-mu-1.2.3-2.2.1" -->
<rss version="2.0" 
	xmlns:content="http://purl.org/rss/1.0/modules/content/">
<channel>
	<title>Comments on: Random Thoughts on the Passing Scene #38</title>
	<link>http://blogs.codegear.com/nickhodges/2007/10/20/38959</link>
	<description>The Blog of the Delphi Product Manager</description>
	<pubDate>Fri, 29 Aug 2008 04:33:06 +0000</pubDate>
	<generator>http://wordpress.org/?v=wordpress-mu-1.2.3-2.2.1</generator>

	<item>
		<title>By: John Kaster</title>
		<link>http://blogs.codegear.com/nickhodges/2007/10/20/38959#comment-4333</link>
		<author>John Kaster</author>
		<pubDate>Mon, 22 Oct 2007 18:48:31 +0000</pubDate>
		<guid>http://blogs.codegear.com/nickhodges/2007/10/20/38959#comment-4333</guid>
		<description>FWIW, 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.</description>
		<content:encoded><![CDATA[<p>FWIW, Michael Beck uploaded the SWAG archive to CodeCentral back in the first year CodeCentral was made public. That&#8217;s why he has so many entries in CodeCentral <img src='http://blogs.codegear.com/nickhodges/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </p>
<p>However, it&#8217;s nice to have a distinctly separate HTML archive of them, too.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Keld R. Hansen</title>
		<link>http://blogs.codegear.com/nickhodges/2007/10/20/38959#comment-4324</link>
		<author>Keld R. Hansen</author>
		<pubDate>Mon, 22 Oct 2007 07:41:32 +0000</pubDate>
		<guid>http://blogs.codegear.com/nickhodges/2007/10/20/38959#comment-4324</guid>
		<description>Chee - 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).</description>
		<content:encoded><![CDATA[<p>Chee - your example still needs class-scope global variables to work, and this is what I don&#8217;t like (and want to avoid).</p>
<p>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&#8217;ll still be implemented as such.</p>
<p>That&#8217;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:=&#8217;&#8230;&#8217; and the compiler should wrap this into a synchronize call without me knowing about it.</p>
<p>That way we could *appear* to have thread-safe VCL, even though it isn&#8217;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).</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: andre</title>
		<link>http://blogs.codegear.com/nickhodges/2007/10/20/38959#comment-4321</link>
		<author>andre</author>
		<pubDate>Mon, 22 Oct 2007 06:54:46 +0000</pubDate>
		<guid>http://blogs.codegear.com/nickhodges/2007/10/20/38959#comment-4321</guid>
		<description>Thread 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!</description>
		<content:encoded><![CDATA[<p>Thread safe VCL? Well, for example to be able to draw text on a TBitmap.Canvas in a thread:</p>
<p>with TBitmap.Create do<br />
begin<br />
  Canvas.Textout(&#8217;test&#8217;)<br />
  Free;<br />
end;</p>
<p>Above example is not possible, because canvas is not threadsafe. But it is not visible at all!</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Chee Wee Chua</title>
		<link>http://blogs.codegear.com/nickhodges/2007/10/20/38959#comment-4288</link>
		<author>Chee Wee Chua</author>
		<pubDate>Sun, 21 Oct 2007 14:02:36 +0000</pubDate>
		<guid>http://blogs.codegear.com/nickhodges/2007/10/20/38959#comment-4288</guid>
		<description>Keld,

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.</description>
		<content:encoded><![CDATA[<p>Keld,</p>
<p>To call VCL functions from a secondary thread without calling Synchronize, use QueueUserAPC. For a complete example, see my comment on Allen&#8217;s blog entry on Spot the deadlock.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Keld Hansen</title>
		<link>http://blogs.codegear.com/nickhodges/2007/10/20/38959#comment-4285</link>
		<author>Keld Hansen</author>
		<pubDate>Sun, 21 Oct 2007 13:27:56 +0000</pubDate>
		<guid>http://blogs.codegear.com/nickhodges/2007/10/20/38959#comment-4285</guid>
		<description>Do 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 :-).</description>
		<content:encoded><![CDATA[<p>Do you *really* need to put locks on *every* call? Couldn&#8217;t it be done by some compiler magic (ie. still do it with "Synchronize", but without me needing to know about it)?</p>
<p>Someling like:</p>
<p>PROCEDURE SetLabelCaption(L : TLabel ; Caption : STRING); Threaded;<br />
  BEGIN<br />
    L.Caption:=Caption<br />
  END;</p>
<p>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.</p>
<p>I do not object to the use of "Synchronize", only to the need for me to know about it :-).</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Joe White</title>
		<link>http://blogs.codegear.com/nickhodges/2007/10/20/38959#comment-4284</link>
		<author>Joe White</author>
		<pubDate>Sun, 21 Oct 2007 12:37:35 +0000</pubDate>
		<guid>http://blogs.codegear.com/nickhodges/2007/10/20/38959#comment-4284</guid>
		<description>BTW, 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.</description>
		<content:encoded><![CDATA[<p>BTW, I&#8217;m mainly interested in being able to create new *forms* from threads. I&#8217;m not so interested in creating a frame from a thread and then parenting it to a form from another thread. (I&#8217;m not sure Windows even allows that.)</p>
<p>Ideally, I&#8217;d like to be able to create those forms with a PopupOwner from a different thread.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Joe White</title>
		<link>http://blogs.codegear.com/nickhodges/2007/10/20/38959#comment-4283</link>
		<author>Joe White</author>
		<pubDate>Sun, 21 Oct 2007 12:28:58 +0000</pubDate>
		<guid>http://blogs.codegear.com/nickhodges/2007/10/20/38959#comment-4283</guid>
		<description>Some 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).</description>
		<content:encoded><![CDATA[<p>Some people probably mean "thread-safe VCL" to mean "let me be lazy and not worry about thread synchronization", which isn&#8217;t realistic (unless you want to drastically slow down the people who actually know what they&#8217;re doing).</p>
<p>That&#8217;s not what I&#8217;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&#8217;s one shared TApplication, one shared TScreen, etc., and they don&#8217;t have any critical sections).</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Nick Hodges</title>
		<link>http://blogs.codegear.com/nickhodges/2007/10/20/38959#comment-4282</link>
		<author>Nick Hodges</author>
		<pubDate>Sun, 21 Oct 2007 12:23:51 +0000</pubDate>
		<guid>http://blogs.codegear.com/nickhodges/2007/10/20/38959#comment-4282</guid>
		<description>Keld --

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</description>
		<content:encoded><![CDATA[<p>Keld &#8211;</p>
<p>The problem with what you want is that it would be mean putting locks around /every/ VCL property call, and I&#8217;m sure you can imagine what that would do to performance.</p>
<p>Nick</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Nick Hodges</title>
		<link>http://blogs.codegear.com/nickhodges/2007/10/20/38959#comment-4280</link>
		<author>Nick Hodges</author>
		<pubDate>Sun, 21 Oct 2007 12:12:59 +0000</pubDate>
		<guid>http://blogs.codegear.com/nickhodges/2007/10/20/38959#comment-4280</guid>
		<description>Thomas --

Indeed I do.  Corrected.  ;-)

Nick</description>
		<content:encoded><![CDATA[<p>Thomas &#8211;</p>
<p>Indeed I do.  Corrected.  <img src='http://blogs.codegear.com/nickhodges/wp-includes/images/smilies/icon_wink.gif' alt=';-)' class='wp-smiley' /> </p>
<p>Nick</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Thomas Mueller</title>
		<link>http://blogs.codegear.com/nickhodges/2007/10/20/38959#comment-4277</link>
		<author>Thomas Mueller</author>
		<pubDate>Sun, 21 Oct 2007 10:11:55 +0000</pubDate>
		<guid>http://blogs.codegear.com/nickhodges/2007/10/20/38959#comment-4277</guid>
		<description>Hi 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</description>
		<content:encoded><![CDATA[<p>Hi Nick,</p>
<p>not to be nitpicking:<br />
"(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.)"</p>
<p>You probably meant "addition", do you?</p>
<p>twm</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Keld Hansen</title>
		<link>http://blogs.codegear.com/nickhodges/2007/10/20/38959#comment-4271</link>
		<author>Keld Hansen</author>
		<pubDate>Sun, 21 Oct 2007 08:27:51 +0000</pubDate>
		<guid>http://blogs.codegear.com/nickhodges/2007/10/20/38959#comment-4271</guid>
		<description>&#62; A lot of customers ask me:  "When are we going to have a
&#62; thread-safe VCL?"  and my initial response is usually this:
&#62; "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"...</description>
		<content:encoded><![CDATA[<p>&gt; A lot of customers ask me:  "When are we going to have a<br />
&gt; thread-safe VCL?"  and my initial response is usually this:<br />
&gt; "What do you mean by a ‘thread-safe VCL’?"</p>
<p>I don&#8217;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.</p>
<p>It can be done - sort of - by using class-scope global variables (f.ex. if you want to update a TLabel&#8217;s caption, I usually code it something like this:</p>
<p>PROCEDURE SetLabelCaption(L : TLabel ; Caption : STRING);<br />
  BEGIN<br />
    ClassGlobalStringVar:=Caption;<br />
    ClassGlobalLabelVar:=L;<br />
    Synchronize(SetLabelFunc)<br />
  END;</p>
<p>PROCEDURE SetLabelFunc;<br />
  BEGIN<br />
    ClassGlobalLabelVar.Caption:=ClassGlobalStringVar<br />
  END;</p>
<p>but it would be much nicer to be able to just do</p>
<p>MainForm.Label.Caption:=&#8217;Progress: &#8216;+IntToStr(Percent)+&#8217;%&#8217;</p>
<p>So, that&#8217;s what *I* mean by "thread-safe VCL"&#8230;</p>
]]></content:encoded>
	</item>
</channel>
</rss>
