<?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: Thread-safe repositories</title> <atom:link href="http://davybrion.com/blog/2008/03/thread-safe-repositories/feed/" rel="self" type="application/rss+xml" /><link>http://davybrion.com/blog/2008/03/thread-safe-repositories/</link> <description>inquisitive: adjective. given to inquiry, research, or asking questions; eager for knowledge; intellectually curious</description> <lastBuildDate>Wed, 16 May 2012 15:43:00 +0000</lastBuildDate> <sy:updatePeriod>hourly</sy:updatePeriod> <sy:updateFrequency>1</sy:updateFrequency> <generator>http://wordpress.org/?v=3.3.2</generator> <item><title>By: The Inquisitive Coder &#187; Blog Archive &#187; Easy non-blocking locking</title><link>http://davybrion.com/blog/2008/03/thread-safe-repositories/comment-page-1/#comment-224</link> <dc:creator>The Inquisitive Coder &#187; Blog Archive &#187; Easy non-blocking locking</dc:creator> <pubDate>Tue, 13 May 2008 09:08:37 +0000</pubDate> <guid
isPermaLink="false">http://ralinx.wordpress.com/?p=84#comment-224</guid> <description>[...] may remember my post about thread-safe repositories from a while ago. In the code from that post, i use the lock keyword to make sure instances of the [...]</description> <content:encoded><![CDATA[<p>[...] may remember my post about thread-safe repositories from a while ago. In the code from that post, i use the lock keyword to make sure instances of the [...]</p> ]]></content:encoded> </item> <item><title>By: Davy Brion</title><link>http://davybrion.com/blog/2008/03/thread-safe-repositories/comment-page-1/#comment-125</link> <dc:creator>Davy Brion</dc:creator> <pubDate>Wed, 26 Mar 2008 18:53:31 +0000</pubDate> <guid
isPermaLink="false">http://ralinx.wordpress.com/?p=84#comment-125</guid> <description>received the following comment from Paul Stovell:Hi Davy,Good article. Just one comment: I’d be careful with code like this:public virtual T FindFirst(Func expression)
{
lock (Monitor)
{
return Members.Values.FirstOrDefault(expression);
}
}Holding a lock whilst calling into user-supplied code can be dangerous. They may call out to a function that also acquires a lock, but that lock may be held by another thread waiting for the results of another query on your repository (that shares the same monitor).Let me give an example:
“Background Synchronizer” thread holds lock on Synchronizer, calls CustomerRepository.FindAll(…) [holding Synchronizer.Monitor, requesting Repository.Monitor]“UI” thread performs search; calls CustomerRepository.FindAll(callback). The callback makes use of the Synchronizer [holding Repository.Monitor, requesting Synchronizer.Monitor]What you end up with is a classic “has A, needs B” while “has B, needs A” deadlock scenario. But your code only controls one of the locks, and their code controls another. Avoiding deadlocks isn’t as simple as avoiding lock B-&gt;lock A in your own class.My preference is to take a snapshot of the objects to process whilst in the lock, and to process them outside of the lock:public virtual T FindFirst(Func expression)
{
List snapshot = new List();
lock (Monitor)
{
snapshot.AddRange(Members.Values);
}
return snapshot.FirstOrDefault(expression)
}Though it may hit problems with a big collection. A more efficient approach is a snapshot invalidation system where you keep your snapshot around until it is invalidated rather than building it every time.Alternatively in this case you may be able to avoid the lock completely - though sometimes it’s unavoidable (saving things, for example).It’s also why I sometimes prefer to use Monitor.TryEnter(lock, timeout) - you avoid deadlocks but suffer/have to plan for exceptions instead. At least you don’t run the risk of tying up every thread in the threadpool.</description> <content:encoded><![CDATA[<p>received the following comment from Paul Stovell:</p><p>Hi Davy,</p><p>Good article. Just one comment: I’d be careful with code like this:</p><p>public virtual T FindFirst(Func expression)<br
/> {<br
/> lock (Monitor)<br
/> {<br
/> return Members.Values.FirstOrDefault(expression);<br
/> }<br
/> }</p><p>Holding a lock whilst calling into user-supplied code can be dangerous. They may call out to a function that also acquires a lock, but that lock may be held by another thread waiting for the results of another query on your repository (that shares the same monitor).</p><p>Let me give an example:<br
/> “Background Synchronizer” thread holds lock on Synchronizer, calls CustomerRepository.FindAll(…) [holding Synchronizer.Monitor, requesting Repository.Monitor]</p><p>“UI” thread performs search; calls CustomerRepository.FindAll(callback). The callback makes use of the Synchronizer [holding Repository.Monitor, requesting Synchronizer.Monitor]</p><p>What you end up with is a classic “has A, needs B” while “has B, needs A” deadlock scenario. But your code only controls one of the locks, and their code controls another. Avoiding deadlocks isn’t as simple as avoiding lock B-&gt;lock A in your own class.</p><p>My preference is to take a snapshot of the objects to process whilst in the lock, and to process them outside of the lock:</p><p>public virtual T FindFirst(Func expression)<br
/> {<br
/> List snapshot = new List();<br
/> lock (Monitor)<br
/> {<br
/> snapshot.AddRange(Members.Values);<br
/> }<br
/> return snapshot.FirstOrDefault(expression)<br
/> }</p><p>Though it may hit problems with a big collection. A more efficient approach is a snapshot invalidation system where you keep your snapshot around until it is invalidated rather than building it every time.</p><p>Alternatively in this case you may be able to avoid the lock completely &#8211; though sometimes it’s unavoidable (saving things, for example).</p><p>It’s also why I sometimes prefer to use Monitor.TryEnter(lock, timeout) &#8211; you avoid deadlocks but suffer/have to plan for exceptions instead. At least you don’t run the risk of tying up every thread in the threadpool.</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 1/21 queries in 0.007 seconds using disk: basic
Object Caching 336/435 objects using disk: basic
Content Delivery Network via Amazon Web Services: CloudFront: d18sni7re4ly7f.cloudfront.net

Served from: davybrion.com @ 2012-05-17 11:15:01 -->
