<?xml version="1.0" encoding="UTF-8"?><rss
version="2.0"
xmlns:content="http://purl.org/rss/1.0/modules/content/"
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:atom="http://www.w3.org/2005/Atom"
xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
> <channel><title>Comments on: The Multithreaded Task Executor</title> <atom:link href="http://davybrion.com/blog/2008/05/the-multithreaded-task-executor/feed/" rel="self" type="application/rss+xml" /><link>http://davybrion.com/blog/2008/05/the-multithreaded-task-executor/</link> <description>inquisitive: adjective. given to inquiry, research, or asking questions; eager for knowledge; intellectually curious</description> <lastBuildDate>Wed, 08 Feb 2012 11:42:42 +0000</lastBuildDate> <sy:updatePeriod>hourly</sy:updatePeriod> <sy:updateFrequency>1</sy:updateFrequency> <generator>http://wordpress.org/?v=3.3.1</generator> <item><title>By: Davy Brion</title><link>http://davybrion.com/blog/2008/05/the-multithreaded-task-executor/comment-page-1/#comment-958</link> <dc:creator>Davy Brion</dc:creator> <pubDate>Thu, 31 Jul 2008 22:13:40 +0000</pubDate> <guid
isPermaLink="false">http://davybrion.com/blog/?p=126#comment-958</guid> <description>hehe yea, statements like &quot;as long as this class is used correctly&quot; always blow up in your face :)and no, i wouldn&#039;t say you&#039;re overly paranoid... when it comes to threading it&#039;s probably best to be paranoid ;)</description> <content:encoded><![CDATA[<p>hehe yea, statements like &#8220;as long as this class is used correctly&#8221; always blow up in your face <img
src='http://d18sni7re4ly7f.cloudfront.net/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /></p><p>and no, i wouldn&#8217;t say you&#8217;re overly paranoid&#8230; when it comes to threading it&#8217;s probably best to be paranoid <img
src='http://d18sni7re4ly7f.cloudfront.net/blog/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /></p> ]]></content:encoded> </item> <item><title>By: Justin Rudd</title><link>http://davybrion.com/blog/2008/05/the-multithreaded-task-executor/comment-page-1/#comment-957</link> <dc:creator>Justin Rudd</dc:creator> <pubDate>Thu, 31 Jul 2008 21:53:23 +0000</pubDate> <guid
isPermaLink="false">http://davybrion.com/blog/?p=126#comment-957</guid> <description>&lt;blockquote&gt;well, the tasks are queued in a single thread, so the fact that QueueTask doesn’t lock queueMonitor is not that big of a problem, as long as this class is used ‘correctly’&lt;/blockquote&gt;Famous last words! :)The problem (IMHO) is you don&#039;t &quot;know&quot; how Queue is implemented.  Sure you could go dig through with reflector but it was probably not written with multiple threads accessing it at the same time.  So you lock queueMonitor and call Count, but if the other thread is calling QueueTask, it might allocate memory for the underlying array (assuming an array is being used) BEFORE the call to Count.  If the memory gets published BEFORE the actual element is put into the array, then Count returns 1 and Queue.Dequeue could return a null reference as well as reallocate the array that just got allocated.  Back in the QueueTask thread, you are now accessing an element in an array that doesn&#039;t exist.I&#039;m probably being overly paranoid, but consider the following code...&lt;code&gt;for(int i = 0; i &lt; m_RemainingWork; ++i)&lt;/code&gt;The above code caused a very subtle race condition because some other code was calling Interlocked.Decrement(ref m_RemainingWork).  The dev thought that the original for loop would completely execute before any of the background threads reduced m_RemainingWork.  And on his Vista box, that is exactly what happened.  On my 2008 server box (which treats all threads as equals), it blew up every time.And one other observation, your ProcessTasks is going to take up quite a bit of CPU because it is basically a SpinLock waiting on work.  There is no niceness there.  The threads will continually look for work without every taking a break.  Not sure about your use cases, so maybe there is a steady stream of work coming in and that doesn&#039;t happen.And yes, I mean pass the wait handle as the state.  The lambda is redundant.  You&#039;ll have to cast instead (from object to WaitHandle).  I love lambdas (I wrote a whole logging library using them - http://www.codeplex.com/LiveLabsLogging), but I generally don&#039;t use them if I don&#039;t have to.  But that&#039;s just my opinion.</description> <content:encoded><![CDATA[<blockquote><p>well, the tasks are queued in a single thread, so the fact that QueueTask doesn’t lock queueMonitor is not that big of a problem, as long as this class is used ‘correctly’</p></blockquote><p>Famous last words! <img
src='http://d18sni7re4ly7f.cloudfront.net/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /></p><p>The problem (IMHO) is you don&#8217;t &#8220;know&#8221; how Queue is implemented.  Sure you could go dig through with reflector but it was probably not written with multiple threads accessing it at the same time.  So you lock queueMonitor and call Count, but if the other thread is calling QueueTask, it might allocate memory for the underlying array (assuming an array is being used) BEFORE the call to Count.  If the memory gets published BEFORE the actual element is put into the array, then Count returns 1 and Queue.Dequeue could return a null reference as well as reallocate the array that just got allocated.  Back in the QueueTask thread, you are now accessing an element in an array that doesn&#8217;t exist.</p><p>I&#8217;m probably being overly paranoid, but consider the following code&#8230;</p><p><code>for(int i = 0; i &lt; m_RemainingWork; ++i)</code></p><p>The above code caused a very subtle race condition because some other code was calling Interlocked.Decrement(ref m_RemainingWork).  The dev thought that the original for loop would completely execute before any of the background threads reduced m_RemainingWork.  And on his Vista box, that is exactly what happened.  On my 2008 server box (which treats all threads as equals), it blew up every time.</p><p>And one other observation, your ProcessTasks is going to take up quite a bit of CPU because it is basically a SpinLock waiting on work.  There is no niceness there.  The threads will continually look for work without every taking a break.  Not sure about your use cases, so maybe there is a steady stream of work coming in and that doesn&#8217;t happen.</p><p>And yes, I mean pass the wait handle as the state.  The lambda is redundant.  You&#8217;ll have to cast instead (from object to WaitHandle).  I love lambdas (I wrote a whole logging library using them &#8211; <a
href="http://www.codeplex.com/LiveLabsLogging" rel="nofollow">http://www.codeplex.com/LiveLabsLogging</a>), but I generally don&#8217;t use them if I don&#8217;t have to.  But that&#8217;s just my opinion.</p> ]]></content:encoded> </item> <item><title>By: Davy Brion</title><link>http://davybrion.com/blog/2008/05/the-multithreaded-task-executor/comment-page-1/#comment-842</link> <dc:creator>Davy Brion</dc:creator> <pubDate>Tue, 22 Jul 2008 20:29:33 +0000</pubDate> <guid
isPermaLink="false">http://davybrion.com/blog/?p=126#comment-842</guid> <description>well, the tasks are queued in a single thread, so the fact that QueueTask doesn&#039;t lock queueMonitor is not that big of a problem, as long as this class is used &#039;correctly&#039;.  But it definitely would be better if it simply locked in that method as well though, you&#039;re definitely right about that :)but what state do you think i should pass to the constructor of the Thread? Do you mean getting rid of the lambda, and passing the WaitHandle as the state object reference?And yes, Parallel Framework for .NET is on my TODO list :p
And yes, i will wait until the final release :p</description> <content:encoded><![CDATA[<p>well, the tasks are queued in a single thread, so the fact that QueueTask doesn&#8217;t lock queueMonitor is not that big of a problem, as long as this class is used &#8216;correctly&#8217;.  But it definitely would be better if it simply locked in that method as well though, you&#8217;re definitely right about that <img
src='http://d18sni7re4ly7f.cloudfront.net/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /></p><p>but what state do you think i should pass to the constructor of the Thread? Do you mean getting rid of the lambda, and passing the WaitHandle as the state object reference?</p><p>And yes, Parallel Framework for .NET is on my TODO list :p<br
/> And yes, i will wait until the final release :p</p> ]]></content:encoded> </item> <item><title>By: Justin Rudd</title><link>http://davybrion.com/blog/2008/05/the-multithreaded-task-executor/comment-page-1/#comment-840</link> <dc:creator>Justin Rudd</dc:creator> <pubDate>Tue, 22 Jul 2008 20:18:29 +0000</pubDate> <guid
isPermaLink="false">http://davybrion.com/blog/?p=126#comment-840</guid> <description>You lock &lt;code&gt;queueMonitor&lt;/code&gt; in &lt;code&gt;GetTask&lt;/code&gt;, but you don&#039;t lock it in &lt;code&gt;QueueTask&lt;/code&gt; so you could still corrupt the queue or have bad reads of the memory.  Since you are using an anonymous lambda in the constructor of thread, you should know that &lt;code&gt;Thread&lt;/code&gt; now has a constructor which takes an &lt;code&gt;object&lt;/code&gt; as a parameter that it can pass as state to your thread procedure.Oh yeah...if you haven&#039;t already check out the &lt;a href=&quot;http://blogs.msdn.com/pfxteam/&quot; rel=&quot;nofollow&quot;&gt;Parallel Framework for .NET&lt;/a&gt;.  It has a nice Task management system complete with Futures.  Although it would definitely break your &quot;don&#039;t touch till released rule&quot; :)</description> <content:encoded><![CDATA[<p>You lock <code>queueMonitor</code> in <code>GetTask</code>, but you don&#8217;t lock it in <code>QueueTask</code> so you could still corrupt the queue or have bad reads of the memory.  Since you are using an anonymous lambda in the constructor of thread, you should know that <code>Thread</code> now has a constructor which takes an <code>object</code> as a parameter that it can pass as state to your thread procedure.</p><p>Oh yeah&#8230;if you haven&#8217;t already check out the <a
href="http://blogs.msdn.com/pfxteam/" rel="nofollow">Parallel Framework for .NET</a>.  It has a nice Task management system complete with Futures.  Although it would definitely break your &#8220;don&#8217;t touch till released rule&#8221; <img
src='http://d18sni7re4ly7f.cloudfront.net/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /></p> ]]></content:encoded> </item> </channel> </rss>
<!-- Performance optimized by W3 Total Cache. Learn more: http://www.w3-edge.com/wordpress-plugins/

Minified using disk: basic
Page Caching using disk: enhanced
Database Caching 2/8 queries in 0.005 seconds using disk: basic
Object Caching 385/386 objects using disk: basic
Content Delivery Network via Amazon Web Services: CloudFront: d18sni7re4ly7f.cloudfront.net

Served from: davybrion.com @ 2012-02-08 18:14:45 -->
