<?xml version="1.0" encoding="utf-8"?>
<rss xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:pingback="http://madskills.com/public/xml/rss/module/pingback/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:dc="http://purl.org/dc/elements/1.1/" version="2.0">
  <channel>
    <title>Oren Ellenbogen's Blog</title>
    <link>http://lnbogen.com/</link>
    <description>Striving for agile development</description>
    <language>en-us</language>
    <copyright>Oren Ellenbogen</copyright>
    <lastBuildDate>Wed, 20 Jan 2010 16:42:49 GMT</lastBuildDate>
    <generator>newtelligence dasBlog 2.2.8279.16125</generator>
    <managingEditor>oren.ellenbogen@gmail.com</managingEditor>
    <webMaster>oren.ellenbogen@gmail.com</webMaster>
    <item>
      <trackback:ping>http://lnbogen.com/Trackback.aspx?guid=3e4ee18b-a5f3-46a7-8f8f-1c2bb831b853</trackback:ping>
      <pingback:server>http://lnbogen.com/pingback.aspx</pingback:server>
      <pingback:target>http://lnbogen.com/PermaLink,guid,3e4ee18b-a5f3-46a7-8f8f-1c2bb831b853.aspx</pingback:target>
      <dc:creator>Oren Ellenbogen</dc:creator>
      <wfw:comment>http://lnbogen.com/CommentView,guid,3e4ee18b-a5f3-46a7-8f8f-1c2bb831b853.aspx</wfw:comment>
      <wfw:commentRss>http://lnbogen.com/SyndicationService.asmx/GetEntryCommentsRss?guid=3e4ee18b-a5f3-46a7-8f8f-1c2bb831b853</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
I’ve spent around 2 hours to figure it out, so at least I’ll write it down. 
<br />
I’m using dotTrace 3.1 to do some analysis for .net web application running on Windows
Server 2008 R2 (IIS 7.5).
</p>
        <p>
I got strange numbers and was missing some data (methods calls) running “profile web
application” until I set the affinity of the w3wp.exe process to single Node (single
core). This can be done easily by opening the Tasks Manager, right click on w3wp process
–&gt; Set Affinity –&gt; pick just one core.
</p>
        <p>
Only then you should record the required page(s) and take the snapshot.
</p>
        <img width="0" height="0" src="http://lnbogen.com/aggbug.ashx?id=3e4ee18b-a5f3-46a7-8f8f-1c2bb831b853" />
      </body>
      <title>Running dotTrace 3.1 on multi-core machine</title>
      <guid isPermaLink="false">http://lnbogen.com/PermaLink,guid,3e4ee18b-a5f3-46a7-8f8f-1c2bb831b853.aspx</guid>
      <link>http://lnbogen.com/2010/01/20/RunningDotTrace31OnMulticoreMachine.aspx</link>
      <pubDate>Wed, 20 Jan 2010 16:42:49 GMT</pubDate>
      <description>&lt;p&gt;
I’ve spent around 2 hours to figure it out, so at least I’ll write it down. 
&lt;br /&gt;
I’m using dotTrace 3.1 to do some analysis for .net web application running on Windows
Server 2008 R2 (IIS 7.5).
&lt;/p&gt;
&lt;p&gt;
I got strange numbers and was missing some data (methods calls) running “profile web
application” until I set the affinity of the w3wp.exe process to single Node (single
core). This can be done easily by opening the Tasks Manager, right click on w3wp process
–&amp;gt; Set Affinity –&amp;gt; pick just one core.
&lt;/p&gt;
&lt;p&gt;
Only then you should record the required page(s) and take the snapshot.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://lnbogen.com/aggbug.ashx?id=3e4ee18b-a5f3-46a7-8f8f-1c2bb831b853" /&gt;</description>
      <comments>http://lnbogen.com/CommentView,guid,3e4ee18b-a5f3-46a7-8f8f-1c2bb831b853.aspx</comments>
    </item>
    <item>
      <trackback:ping>http://lnbogen.com/Trackback.aspx?guid=2335d26b-d8fa-4f26-a4d7-53f42afcb67a</trackback:ping>
      <pingback:server>http://lnbogen.com/pingback.aspx</pingback:server>
      <pingback:target>http://lnbogen.com/PermaLink,guid,2335d26b-d8fa-4f26-a4d7-53f42afcb67a.aspx</pingback:target>
      <dc:creator>Oren Ellenbogen</dc:creator>
      <wfw:comment>http://lnbogen.com/CommentView,guid,2335d26b-d8fa-4f26-a4d7-53f42afcb67a.aspx</wfw:comment>
      <wfw:commentRss>http://lnbogen.com/SyndicationService.asmx/GetEntryCommentsRss?guid=2335d26b-d8fa-4f26-a4d7-53f42afcb67a</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
During team’s growth, the practice of keeping the knowledge base sound, looks like
mission impossible. There are simply too many concerns to write down and maintain:
picking a proper (=”searchable”) title to the knowledge base item, keeping the history
of changes in the design and why they were made, adding some drawing etc. Text notes
(and pretty pictures), what can we do, are getting obsolete extremely fast. 
</p>
        <blockquote>
          <p>
“How can we keep the team’s knowledge base without running after our tail?”
</p>
        </blockquote>
        <p>
My team came up with this suggestion:
</p>
        <blockquote>
          <p>
“Let’s keep the titles and put owners next to it, the rest can be solved with good
communication and tests!”
</p>
        </blockquote>
        <p>
Examples for such “knowledge base items” are, from our real list:
</p>
        <ul>
          <li>
Supporting Contextual Sign-In scenarios (Avish) 
</li>
          <li>
Common CSS Classes for our beautiful look-and-feel (Moran) 
</li>
          <li>
Creating and using pretty-URL routes (Ken) 
</li>
          <li>
… 
</li>
        </ul>
        <p>
          <br />
We broke it into domains like “basic architecture”, “common features”, “cross-cutting
concerns”. Now the list is easy to search at (wiki) and fun to maintain. 
<br /><br />
This work extremely well if:
</p>
        <ul>
          <li>
Code-reviews are done on a regular basis. This means that at least 2 developers can
talk about each knowledge base item. 
</li>
          <li>
Tests are written to built great confidence (to refactor easily) in the code. I talk
about unit-testing, integration testing, UI testing etc. 
<ul><li>
Great tests explain how to use the API and what should be expected from it. 
</li><li>
Tests (mostly integration tests) explain the latest architecture. 
</li></ul></li>
          <li>
Comments in code should include the “why” behind the logic. Team members can add to
it even more if needed, by talking with each other. 
</li>
          <li>
New developers are exposed to the knowledge base, talking with the relevant owners.
This is a great reference to look at. 
</li>
        </ul>
        <p>
Simple, short, effective!
</p>
        <img width="0" height="0" src="http://lnbogen.com/aggbug.ashx?id=2335d26b-d8fa-4f26-a4d7-53f42afcb67a" />
      </body>
      <title>Keeping team’s knowledge base</title>
      <guid isPermaLink="false">http://lnbogen.com/PermaLink,guid,2335d26b-d8fa-4f26-a4d7-53f42afcb67a.aspx</guid>
      <link>http://lnbogen.com/2009/09/17/KeepingTeamsKnowledgeBase.aspx</link>
      <pubDate>Thu, 17 Sep 2009 12:59:11 GMT</pubDate>
      <description>&lt;p&gt;
During team’s growth, the practice of keeping the knowledge base sound, looks like
mission impossible. There are simply too many concerns to write down and maintain:
picking a proper (=”searchable”) title to the knowledge base item, keeping the history
of changes in the design and why they were made, adding some drawing etc. Text notes
(and pretty pictures), what can we do, are getting obsolete extremely fast. 
&lt;/p&gt;
&lt;blockquote&gt; 
&lt;p&gt;
“How can we keep the team’s knowledge base without running after our tail?”
&lt;/p&gt;
&lt;/blockquote&gt; 
&lt;p&gt;
My team came up with this suggestion:
&lt;/p&gt;
&lt;blockquote&gt; 
&lt;p&gt;
“Let’s keep the titles and put owners next to it, the rest can be solved with good
communication and tests!”
&lt;/p&gt;
&lt;/blockquote&gt; 
&lt;p&gt;
Examples for such “knowledge base items” are, from our real list:
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
Supporting Contextual Sign-In scenarios (Avish) 
&lt;/li&gt;
&lt;li&gt;
Common CSS Classes for our beautiful look-and-feel (Moran) 
&lt;/li&gt;
&lt;li&gt;
Creating and using pretty-URL routes (Ken) 
&lt;/li&gt;
&lt;li&gt;
… 
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
&lt;br /&gt;
We broke it into domains like “basic architecture”, “common features”, “cross-cutting
concerns”. Now the list is easy to search at (wiki) and fun to maintain. 
&lt;br /&gt;
&lt;br /&gt;
This work extremely well if:
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
Code-reviews are done on a regular basis. This means that at least 2 developers can
talk about each knowledge base item. 
&lt;/li&gt;
&lt;li&gt;
Tests are written to built great confidence (to refactor easily) in the code. I talk
about unit-testing, integration testing, UI testing etc. 
&lt;ul&gt;
&lt;li&gt;
Great tests explain how to use the API and what should be expected from it. 
&lt;/li&gt;
&lt;li&gt;
Tests (mostly integration tests) explain the latest architecture. 
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
Comments in code should include the “why” behind the logic. Team members can add to
it even more if needed, by talking with each other. 
&lt;/li&gt;
&lt;li&gt;
New developers are exposed to the knowledge base, talking with the relevant owners.
This is a great reference to look at. 
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
Simple, short, effective!
&lt;/p&gt;
&lt;img width="0" height="0" src="http://lnbogen.com/aggbug.ashx?id=2335d26b-d8fa-4f26-a4d7-53f42afcb67a" /&gt;</description>
      <comments>http://lnbogen.com/CommentView,guid,2335d26b-d8fa-4f26-a4d7-53f42afcb67a.aspx</comments>
    </item>
    <item>
      <trackback:ping>http://lnbogen.com/Trackback.aspx?guid=8c1d064e-af42-4751-ab4c-76a7c4b993ca</trackback:ping>
      <pingback:server>http://lnbogen.com/pingback.aspx</pingback:server>
      <pingback:target>http://lnbogen.com/PermaLink,guid,8c1d064e-af42-4751-ab4c-76a7c4b993ca.aspx</pingback:target>
      <dc:creator>Oren Ellenbogen</dc:creator>
      <wfw:comment>http://lnbogen.com/CommentView,guid,8c1d064e-af42-4751-ab4c-76a7c4b993ca.aspx</wfw:comment>
      <wfw:commentRss>http://lnbogen.com/SyndicationService.asmx/GetEntryCommentsRss?guid=8c1d064e-af42-4751-ab4c-76a7c4b993ca</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <h3>Great dishes. Great timing. <strong>Every single day. This is one amazing place
to eat at!</strong></h3>
        <p>
In many ways, running a great team of developers is just like running top-quality
kitchen. 
<br />
You’re measured by your ability to serve great quality(CI? well tested?), super tasty(nice
UI?) dishes (features?), to hungry people (clients?) in reasonable time (before they’ll
leave to another site).
</p>
        <h3>Without solid understanding of ETA, there is no way to predict quality and release
in time.
</h3>
        <p>
Most of us are driven by what life has to throw on us, may it be some personal event,
a new book you read that makes you want to refactor everything or simply a lot of
context-switches between projects and bugs. 
<br />
Add this to our constant urge to excel at what we do, and you get a “miraculous” skill
of losing control over our time. We’re built this way. <strong>Life is pushing us
around!</strong></p>
        <p>
How does this effect us or the “wheel” I’m talking about? I want to introduce you
to Joe.  
<br />
Joe is a nice guy in my imaginary world, working as a superstar developer for “TheBestOutThere”
company. Joe was assigned to complete a feature and asked to estimate when it will
be done. “This feature is quite simple”, he shoots fast, “a few changes here, a few
there and then the UI to nail the all thing. Hmmm… I guess that <strong>no more than
2 days of work</strong>”. So our story begins…
</p>
        <p>
The first day goes pretty well as Joe adding the needed fields to the database and
even manage to complete some tasks regarding the logic needed. On the second day (reminder:
the last day according to the ETA) things starting to bite Joe’s ass. The feature
turns to be a bit more difficult than he anticipated, and he feels that it will take
2 extra hours to complete the work. Keeping it in mind, he already notifies the wife
he’s going to be late today. “Damn, late again?”, he ponders, “oh well, at least I
know what is left to do now”. Knowing that he needs to leave late today, he continues
to work and suddenly he detects a really ugly piece of code in his path. “Refactoring
time baby!”, he smiles to himself. “Well, I already have a few spare hours, why not?”,
he convince himself once more. It works. The refactoring takes additional 4 hours.
Joe, in a panic attack understands that it took more than he planned, hurries up missing
a few critical tests and canceling the “code review” meeting claiming “this feature
is simple enough!”. The code-review still takes place as this is simply a must for
top-quality kitchens. Fixing the code review comments, including adding the missing
tests (as needed to begin with) cost a few more hours and so <strong>days starting
to fly by</strong>. After 5 days, Joe moving the feature to “code-ready”, now waiting
for QA to test the feature. QA opens about 7 bugs, which take 6 more hours to fix
(with solid unit tests to reproduce these bugs). On top of it, some more fixes were
needed for easy deployment later on in production. <strong>The feature took total
of about 7 days</strong>. Where is the missing 5 days went to? is Joe simply a poor
estimator? Not quite, he just suffer from bad “context” we all do. He suffers from
the constant battle between deliver fast and deliver with high quality. The problem
is that it’s really hard to understand how estimation and quality work together.
</p>
        <h4>If ETA is Jesus, Quality is God. Which is more tangible?
</h4>
        <p>
People are wasting time trying to convince themselves they can outperform on a daily
basis. We can’t. Our best is probably not as great as we imagine. Instead, let’s not
try to improve our ability to code faster, think faster or drink more coffee. Even
if you manage to get better at it (or consume more coffee and urinate to a cup), it
won’t last for long (urine tends to stink in the room).
</p>
        <p>
Instead, think carefully about “where the hack my 5 more days went to? Could I see
it coming?” 
<br />
Here is the “context” Joe needed to have in order to produce a <strong>complete</strong> feature,
with great quality, in time:
</p>
        <ol>
          <li>
Did I spare enough time reading the spec and talking with the Product Manager about
it? (yes, this <strong>is</strong> part of the feature!)</li>
          <li>
Did I make sure there are no open issues left?</li>
          <li>
Did I spare time thinking about how this feature will be tested? how we can automate
these tests easily?</li>
          <li>
Did I spare time to design the solution and do the required review with other people?
what about the hours needed to fix your solution based on the reviews?</li>
          <li>
Did I spare time to read QA test cases and give feedback on it?</li>
          <li>
Do I have everything you need to make the feature a huge success? 
</li>
        </ol>
        <ol>
          <li>
What about people helping you out where needed? 
</li>
        </ol>
        <li>
Did I spare enough time to write the code itself? are you sure?</li>
        <li>
Did I spare time for testing? I talk about really great testing (unit tests, integration
tests, automated UI tests, manual UI tests)</li>
        <ol>
          <li>
Again, the goal here is great confidence in quality, not 100% test coverage.</li>
        </ol>
        <li>
Did I spare time for code reviews? for code reviews fixes?</li>
        <li>
Did I spare time thinking about how this feature will be deployed?</li>
        <li>
Did I spare time sitting with the Product Manager again on your <strong>final result</strong> before
merging your work back to “trunk”? (do it now as it’s “hot”)</li>
        <li>
Did I spare time for “bug fixing buffer” (saving ~10% of the feature time for bug
fixing is a good start, try to reduce later)?</li>
        <p>
Estimating each one of these steps (use “buffers” if certainty is low) and you’re
a bit closer to understand where the missing 5 days vanished.  
<br />
Joe was thinking only about the <strong>coding</strong> effort, not the <strong>entire
picture</strong>! This, by nature, means inability to consistently predict when something
will end. He was pricing the wrong thing!
</p>
        <h4>What does it take to make your team great unit of brilliant minds producing great
dishes, every time:
</h4>
        <ol>
          <li>
Hire the best. They simply worth it. (oh well, that was easy, right? :))</li>
          <li>
Trust them doing the best work one can do! Help them get them but don’t think they
can’t get there by themselves with the right set of tools and context.</li>
          <li>
Start with explaining the meaning of great ETA - without it, prediction is impossible.
Consistency is a lost cause. This is one bad kitchen.</li>
          <li>
Ask people to stand behind there ETA. <strong>They</strong> are <strong>responsible</strong> for
it!</li>
          <li>
In the same breath, remind them that quality work is the right path to get a correct
ETA. Quality work will lead to shorter cycle eventually! 
</li>
          <li>
But (here comes to tricky part!), they should also remember that over-refactoring
leads to <strong>high quality of nothing important</strong> (as nothing really reach
production).</li>
          <li>
So, define together what is “quality work”. Set it as “team context”.</li>
          <li>
Constantly hear what your guys has to say about “I wish we could fix it!”. Eliminate
the big things (lack of tools, too many context-switches, not enough testing etc).</li>
          <li>
Try to inject a lot of honesty, communication and great motivation to the team. This
is the basic engine oil no one can live without.</li>
          <li>
Measure delivery cycle length: spec –&gt; design –&gt; getting ETA –&gt; feature is
code-ready –&gt; solving all bugs –&gt; deployed in production.</li>
          <li>
Talk with your guys to understand waste again. Eliminate the big things now! seriously!</li>
          <li>
Keep hiring more people, only the best, you’ll need them soon enough.</li>
        </ol>
        <p>
Over time, the cycle of delivery should get much better while the quality will get
even higher. The trick here is that people will feel more confident in the flow, “saving'”
time to write quality piece of code, making features amazingly stable in the 1st attempt. <strong>This
is the consistent rhythm you should dream of. The wheel spins…</strong></p>
        <img width="0" height="0" src="http://lnbogen.com/aggbug.ashx?id=8c1d064e-af42-4751-ab4c-76a7c4b993ca" />
      </body>
      <title>Estimations spin the wheel</title>
      <guid isPermaLink="false">http://lnbogen.com/PermaLink,guid,8c1d064e-af42-4751-ab4c-76a7c4b993ca.aspx</guid>
      <link>http://lnbogen.com/2009/09/16/EstimationsSpinTheWheel.aspx</link>
      <pubDate>Wed, 16 Sep 2009 10:38:45 GMT</pubDate>
      <description>&lt;h3&gt;Great dishes. Great timing. &lt;strong&gt;Every single day. This is one amazing place
to eat at!&lt;/strong&gt;
&lt;/h3&gt;
&lt;p&gt;
In many ways, running a great team of developers is just like running top-quality
kitchen. 
&lt;br /&gt;
You’re measured by your ability to serve great quality(CI? well tested?), super tasty(nice
UI?) dishes (features?), to hungry people (clients?) in reasonable time (before they’ll
leave to another site).
&lt;/p&gt;
&lt;h3&gt;Without solid understanding of ETA, there is no way to predict quality and release
in time.
&lt;/h3&gt;
&lt;p&gt;
Most of us are driven by what life has to throw on us, may it be some personal event,
a new book you read that makes you want to refactor everything or simply a lot of
context-switches between projects and bugs. 
&lt;br /&gt;
Add this to our constant urge to excel at what we do, and you get a “miraculous” skill
of losing control over our time. We’re built this way. &lt;strong&gt;Life is pushing us
around!&lt;/strong&gt;
&lt;/p&gt;
&lt;p&gt;
How does this effect us or the “wheel” I’m talking about? I want to introduce you
to Joe.&amp;#160; 
&lt;br /&gt;
Joe is a nice guy in my imaginary world, working as a superstar developer for “TheBestOutThere”
company. Joe was assigned to complete a feature and asked to estimate when it will
be done. “This feature is quite simple”, he shoots fast, “a few changes here, a few
there and then the UI to nail the all thing. Hmmm… I guess that &lt;strong&gt;no more than
2 days of work&lt;/strong&gt;”. So our story begins…
&lt;/p&gt;
&lt;p&gt;
The first day goes pretty well as Joe adding the needed fields to the database and
even manage to complete some tasks regarding the logic needed. On the second day (reminder:
the last day according to the ETA) things starting to bite Joe’s ass. The feature
turns to be a bit more difficult than he anticipated, and he feels that it will take
2 extra hours to complete the work. Keeping it in mind, he already notifies the wife
he’s going to be late today. “Damn, late again?”, he ponders, “oh well, at least I
know what is left to do now”. Knowing that he needs to leave late today, he continues
to work and suddenly he detects a really ugly piece of code in his path. “Refactoring
time baby!”, he smiles to himself. “Well, I already have a few spare hours, why not?”,
he convince himself once more. It works. The refactoring takes additional 4 hours.
Joe, in a panic attack understands that it took more than he planned, hurries up missing
a few critical tests and canceling the “code review” meeting claiming “this feature
is simple enough!”. The code-review still takes place as this is simply a must for
top-quality kitchens. Fixing the code review comments, including adding the missing
tests (as needed to begin with) cost a few more hours and so &lt;strong&gt;days starting
to fly by&lt;/strong&gt;. After 5 days, Joe moving the feature to “code-ready”, now waiting
for QA to test the feature. QA opens about 7 bugs, which take 6 more hours to fix
(with solid unit tests to reproduce these bugs). On top of it, some more fixes were
needed for easy deployment later on in production. &lt;strong&gt;The feature took total
of about 7 days&lt;/strong&gt;. Where is the missing 5 days went to? is Joe simply a poor
estimator? Not quite, he just suffer from bad “context” we all do. He suffers from
the constant battle between deliver fast and deliver with high quality. The problem
is that it’s really hard to understand how estimation and quality work together.
&lt;/p&gt;
&lt;h4&gt;If ETA is Jesus, Quality is God. Which is more tangible?
&lt;/h4&gt;
&lt;p&gt;
People are wasting time trying to convince themselves they can outperform on a daily
basis. We can’t. Our best is probably not as great as we imagine. Instead, let’s not
try to improve our ability to code faster, think faster or drink more coffee. Even
if you manage to get better at it (or consume more coffee and urinate to a cup), it
won’t last for long (urine tends to stink in the room).
&lt;/p&gt;
&lt;p&gt;
Instead, think carefully about “where the hack my 5 more days went to? Could I see
it coming?” 
&lt;br /&gt;
Here is the “context” Joe needed to have in order to produce a &lt;strong&gt;complete&lt;/strong&gt; feature,
with great quality, in time:
&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
Did I spare enough time reading the spec and talking with the Product Manager about
it? (yes, this &lt;strong&gt;is&lt;/strong&gt; part of the feature!)&lt;/li&gt;
&lt;li&gt;
Did I make sure there are no open issues left?&lt;/li&gt;
&lt;li&gt;
Did I spare time thinking about how this feature will be tested? how we can automate
these tests easily?&lt;/li&gt;
&lt;li&gt;
Did I spare time to design the solution and do the required review with other people?
what about the hours needed to fix your solution based on the reviews?&lt;/li&gt;
&lt;li&gt;
Did I spare time to read QA test cases and give feedback on it?&lt;/li&gt;
&lt;li&gt;
Do I have everything you need to make the feature a huge success? 
&lt;/li&gt;
&lt;ol&gt;
&lt;li&gt;
What about people helping you out where needed? 
&lt;/li&gt;
&lt;/ol&gt;
&lt;li&gt;
Did I spare enough time to write the code itself? are you sure?&lt;/li&gt;
&lt;li&gt;
Did I spare time for testing? I talk about really great testing (unit tests, integration
tests, automated UI tests, manual UI tests)&lt;/li&gt;
&lt;ol&gt;
&lt;li&gt;
Again, the goal here is great confidence in quality, not 100% test coverage.&lt;/li&gt;
&lt;/ol&gt;
&lt;li&gt;
Did I spare time for code reviews? for code reviews fixes?&lt;/li&gt;
&lt;li&gt;
Did I spare time thinking about how this feature will be deployed?&lt;/li&gt;
&lt;li&gt;
Did I spare time sitting with the Product Manager again on your &lt;strong&gt;final result&lt;/strong&gt; before
merging your work back to “trunk”? (do it now as it’s “hot”)&lt;/li&gt;
&lt;li&gt;
Did I spare time for “bug fixing buffer” (saving ~10% of the feature time for bug
fixing is a good start, try to reduce later)?&lt;/li&gt;
&gt;
&lt;p&gt;
Estimating each one of these steps (use “buffers” if certainty is low) and you’re
a bit closer to understand where the missing 5 days vanished.&amp;#160; 
&lt;br /&gt;
Joe was thinking only about the &lt;strong&gt;coding&lt;/strong&gt; effort, not the &lt;strong&gt;entire
picture&lt;/strong&gt;! This, by nature, means inability to consistently predict when something
will end. He was pricing the wrong thing!
&lt;/p&gt;
&lt;h4&gt;What does it take to make your team great unit of brilliant minds producing great
dishes, every time:
&lt;/h4&gt;
&lt;ol&gt;
&lt;li&gt;
Hire the best. They simply worth it. (oh well, that was easy, right? :))&lt;/li&gt;
&lt;li&gt;
Trust them doing the best work one can do! Help them get them but don’t think they
can’t get there by themselves with the right set of tools and context.&lt;/li&gt;
&lt;li&gt;
Start with explaining the meaning of great ETA - without it, prediction is impossible.
Consistency is a lost cause. This is one bad kitchen.&lt;/li&gt;
&lt;li&gt;
Ask people to stand behind there ETA. &lt;strong&gt;They&lt;/strong&gt; are &lt;strong&gt;responsible&lt;/strong&gt; for
it!&lt;/li&gt;
&lt;li&gt;
In the same breath, remind them that quality work is the right path to get a correct
ETA. Quality work will lead to shorter cycle eventually! 
&lt;/li&gt;
&lt;li&gt;
But (here comes to tricky part!), they should also remember that over-refactoring
leads to &lt;strong&gt;high quality of nothing important&lt;/strong&gt; (as nothing really reach
production).&lt;/li&gt;
&lt;li&gt;
So, define together what is “quality work”. Set it as “team context”.&lt;/li&gt;
&lt;li&gt;
Constantly hear what your guys has to say about “I wish we could fix it!”. Eliminate
the big things (lack of tools, too many context-switches, not enough testing etc).&lt;/li&gt;
&lt;li&gt;
Try to inject a lot of honesty, communication and great motivation to the team. This
is the basic engine oil no one can live without.&lt;/li&gt;
&lt;li&gt;
Measure delivery cycle length: spec –&amp;gt; design –&amp;gt; getting ETA –&amp;gt; feature is
code-ready –&amp;gt; solving all bugs –&amp;gt; deployed in production.&lt;/li&gt;
&lt;li&gt;
Talk with your guys to understand waste again. Eliminate the big things now! seriously!&lt;/li&gt;
&lt;li&gt;
Keep hiring more people, only the best, you’ll need them soon enough.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;
Over time, the cycle of delivery should get much better while the quality will get
even higher. The trick here is that people will feel more confident in the flow, “saving'”
time to write quality piece of code, making features amazingly stable in the 1st attempt. &lt;strong&gt;This
is the consistent rhythm you should dream of. The wheel spins…&lt;/strong&gt;
&lt;/p&gt;
&lt;img width="0" height="0" src="http://lnbogen.com/aggbug.ashx?id=8c1d064e-af42-4751-ab4c-76a7c4b993ca" /&gt;</description>
      <comments>http://lnbogen.com/CommentView,guid,8c1d064e-af42-4751-ab4c-76a7c4b993ca.aspx</comments>
    </item>
    <item>
      <trackback:ping>http://lnbogen.com/Trackback.aspx?guid=8b187d37-d165-4882-8714-8e98e082ae55</trackback:ping>
      <pingback:server>http://lnbogen.com/pingback.aspx</pingback:server>
      <pingback:target>http://lnbogen.com/PermaLink,guid,8b187d37-d165-4882-8714-8e98e082ae55.aspx</pingback:target>
      <dc:creator>Oren Ellenbogen</dc:creator>
      <wfw:comment>http://lnbogen.com/CommentView,guid,8b187d37-d165-4882-8714-8e98e082ae55.aspx</wfw:comment>
      <wfw:commentRss>http://lnbogen.com/SyndicationService.asmx/GetEntryCommentsRss?guid=8b187d37-d165-4882-8714-8e98e082ae55</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
Can you count the number of times you were asked with this innocent question? 
</p>
        <p>
I tried to think and analyze the "motivation" behind this question, considering <em>why </em>people
are so intrigued to hear <em>my</em> answer when putting me on the spot. Is it really
that important for others to know what Oren have to say about God? I can't ignore
the simple fact that religion is a huge cornerstone in our life and finding more people
with similar believes give us great comfort and sense of power. People are looking
for acceptance, to become part of a group they can define and feel "right" in. This
is a social aspect that is common to almost everything we do in life (love, friends,
work, faith etc). I already know all of that and so do you. So, where am I going with
this?<br /><br />
I'm trying to muse with the the notion of acceptance and <strong>where do I fit in</strong>.
What is <strong>my</strong> "do you believe in God" question?
</p>
        <p>
Personally, It's striking me as plain crazy that our life is so driven to into what
I grasp as the "wrong" groups. Do you believe in God? Do you eat Kosher food? Do you
fast at Yom Kipor? Are you rightist? And the list goes on and on. Are these the questions
we should really ask ourselves? is these <em>how</em> we want to measure ourselves
or find others to connect with? I'm not sure I know the answers, but I feel there
are some deep feelings, clear ideas and emotional borders that I'm so <strong>passionate</strong> about,
they must represent my scales. They must represent <em>my</em> inner truth. Writing
allow one to shoot ideas and thoughts on paper, so I tried to explain myself my truths.
Hopefully it will give me a common ground to fit myself into a world I truly believe
in and measure myself about what I see as right. Trying to synthesize my list, I came
up with the 3 questions I have definite feeling of, (but) these are only <em>my</em> big
questions so read it with the appropriate suspicion:
</p>
        <ol>
          <li>
            <strong>Are you making someone else proud?<br /></strong>I'm blessed with the best parents one can wish for and the greatest family
one can be born into. The best thing they have done for me is giving me their complete
trust, always stating how much faith they have in me making the right call. It was
really hard for me to mess things up with that kind of love and support. Make sure
that you've got someone in life that you can make them proud, may it be your parents,
family, girlfriend, close friend or the girl from the cafeteria. "I'm proud of you"
is huge empowerment and it's a constant motivator to drive your life beyond the easy
and all-so-common mediocrity. This source should be your impregnable place for positive
enforcement, keeping you down to earth and posses the right confident to make tough
choices in life.<br /><br />
Be careful not to confuse making one proud with making one satisfied. You must own
your path thus there is no place for blind acceptance. You need someone that trust
your best efforts and push you forward in your struggles. 
<br /><br /></li>
          <li>
            <strong>Do you see yourself as a good person?</strong>
            <br />
Let's avoid the definition of good for a second as it doesn't really matter. Although
some of us really cynical about the meaning (and with no doubt some are plain bad),
we all know that Mother Teresa is a good soul. The pure notion of bad and good is
embedded deep inside us. Try to be truthful to yourself, do you see yourself as a
good person? how would you define good? Do you think you can measure "how good" are
you? Do you think it's important? Are you doing what it takes to get "better"? does
it get easier to look at the mirror?<br /><br />
You can call me what ever you might feel, but there is a romantic notion behind "being
good". The way I see it, my time here is limited so my constant question is "what
am I going to leave behind?". I would like to think that I've touched some people
during my short life, that I managed to teach something as my great family and friends
have taught me. I'm not sure that I made a great change (or even a small one), but
at least I feel I did the best I can do with my believe of sincere communication.
I'll never be Mother Teresa, but at least I'll do the best I can with what I feel
is right for me, trying to focus on my strength and talent to make others picking
their brain and wonder about themselves. Being there for others will make you feel
less alone, less "on a road to nowhere". What do you have to lose?<br /><br /></li>
          <li>
            <strong>Is there a way for you to help others?<br /></strong>Do you feel lucky? If you do, you played your cards right somehow. Is there
a way for you to show your tricks to the world? to make others think of a different
way to look at things? Helping others makes a great closure between making others
proud and making you feel as a good person. It's a powerful tool you should use wisely.
The purpose is not the "convert" someone into your believes or trying to bring him
into your "group". One should reach his own right and wrong, you can only help him
by asking the right questions and trying to share your thoughts and experience. This
way you are part of the journey, part of a legacy in other's life. This is a great
accomplishment to leave behind you.<br /></li>
        </ol>
        <p>
The order of the questions is important. Without making others proud and have their
support it's impossible to be highly motivated all the time. Without constant motivation
you won't allow yourself to grow into the person you can become, making it easier
to avoid helping others and seeking for the "wrong kind" of acceptance. <strong>Giving
up is easy, fitting in just for the sake of acceptance will not make you happier (at
least for long).</strong><br /><br />
Don't allow yourself to give up just because you were born to the wrong environment,
that you had troubles as a child or you feel just like the world is against you. The
world don't owe you anything, you can blame your luck, your God (or lack of it) but
bottom line it's really up to you. Don't hurt others to pay back to your awful sense
of luck. Find your positive people around you and let them pick you up when needed,
there is no shame of needing others help, they would love to do so in order to feel
good about themselves and making others proud. You'll do the same for them one day,
I promise you that.<br /><br />
Everyone who knows me are familiar with my reiterative phrase "I firmly believe in
natural growth", this rule apply here as well. Find your own sources of strength and
make sure that you keep your "good standards" before trying to influence others to
ponder about their path in life. Once you have the confidence in your answers, you'll
be ready to open your view to the world and see what it has to offer.
</p>
        <p>
          <br />
          <strong>Do I believe in God?<br /></strong>We're probably ants in a giants world, but is it really matter? I would like
to think that this God cares more about us as living being, trying to grow together
than following strict rules without understanding the real truth behind them. Isn't
this the all purpose of the bible? of the stories we are taught since we were born?
I wish our discussions would address more of the "are we doing the best we can?" and
"how can we make it better?" rather than such a superficial scratch of our real purpose.
</p>
        <p>
I would love to hear what is <strong>your truth </strong>and which questions drive
you in your path<strong>. </strong>Drop me a comment if you feel like sharing.
</p>
        <img width="0" height="0" src="http://lnbogen.com/aggbug.ashx?id=8b187d37-d165-4882-8714-8e98e082ae55" />
      </body>
      <title>Do you believe in God?</title>
      <guid isPermaLink="false">http://lnbogen.com/PermaLink,guid,8b187d37-d165-4882-8714-8e98e082ae55.aspx</guid>
      <link>http://lnbogen.com/2009/02/04/DoYouBelieveInGod.aspx</link>
      <pubDate>Wed, 04 Feb 2009 10:07:28 GMT</pubDate>
      <description>&lt;p&gt;
Can you count the number of times you were asked with this innocent question? 
&lt;/p&gt;
&lt;p&gt;
I tried to think and analyze the "motivation" behind this question, considering &lt;em&gt;why &lt;/em&gt;people
are so intrigued to hear &lt;em&gt;my&lt;/em&gt; answer when putting me on the spot. Is it really
that important for others to know what Oren have to say about God? I can't ignore
the simple fact that religion is a huge cornerstone in our life and finding more people
with similar believes give us great comfort and sense of power. People are looking
for acceptance, to become part of a group they can define and feel "right" in. This
is a social aspect that is common to almost everything we do in life (love, friends,
work, faith etc). I already know all of that and so do you. So, where am I going with
this?&lt;br&gt;
&lt;br&gt;
I'm trying to muse with the the notion of acceptance and &lt;strong&gt;where do I fit in&lt;/strong&gt;.
What is &lt;strong&gt;my&lt;/strong&gt; "do you believe in God" question?
&lt;/p&gt;
&lt;p&gt;
Personally, It's striking me as plain crazy that our life is so driven to into what
I grasp as the "wrong" groups. Do you believe in God? Do you eat Kosher food? Do you
fast at Yom Kipor? Are you rightist? And the list goes on and on. Are these the questions
we should really ask ourselves? is these &lt;em&gt;how&lt;/em&gt; we want to measure ourselves
or find others to connect with? I'm not sure I know the answers, but I feel there
are some deep feelings, clear ideas and emotional borders that I'm so &lt;strong&gt;passionate&lt;/strong&gt; about,
they must represent my scales. They must represent &lt;em&gt;my&lt;/em&gt; inner truth. Writing
allow one to shoot ideas and thoughts on paper, so I tried to explain myself my truths.
Hopefully it will give me a common ground to fit myself into a world I truly believe
in and measure myself about what I see as right. Trying to synthesize my list, I came
up with the 3 questions I have definite feeling of, (but) these are only &lt;em&gt;my&lt;/em&gt; big
questions so read it with the appropriate suspicion:
&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Are you making someone else proud?&lt;br&gt;
&lt;/strong&gt;I'm blessed with the best parents one can wish for and the greatest family
one can be born into. The best thing they have done for me is giving me their complete
trust, always stating how much faith they have in me making the right call. It was
really hard for me to mess things up with that kind of love and support. Make sure
that you've got someone in life that you can make them proud, may it be your parents,
family, girlfriend, close friend or the girl from the cafeteria. "I'm proud of you"
is huge empowerment and it's a constant motivator to drive your life beyond the easy
and all-so-common mediocrity. This source should be your impregnable place for positive
enforcement, keeping you down to earth and posses the right confident to make tough
choices in life.&lt;br&gt;
&lt;br&gt;
Be careful not to confuse making one proud with making one satisfied. You must own
your path thus there is no place for blind acceptance. You need someone that trust
your best efforts and push you forward in your struggles. 
&lt;br&gt;
&lt;br&gt;
&lt;li&gt;
&lt;strong&gt;Do you see yourself as a good person?&lt;/strong&gt;
&lt;br&gt;
Let's avoid the definition of good for a second as it doesn't really matter. Although
some of us really cynical about the meaning (and with no doubt some are plain bad),
we all know that Mother Teresa is a good soul. The pure notion of bad and good is
embedded deep inside us. Try to be truthful to yourself, do you see yourself as a
good person? how would you define good? Do you think you can measure "how good" are
you? Do you think it's important? Are you doing what it takes to get "better"? does
it get easier to look at the mirror?&lt;br&gt;
&lt;br&gt;
You can call me what ever you might feel, but there is a romantic notion behind "being
good". The way I see it, my time here is limited so my constant question is "what
am I going to leave behind?". I would like to think that I've touched some people
during my short life, that I managed to teach something as my great family and friends
have taught me. I'm not sure that I made a great change (or even a small one), but
at least I feel I did the best I can do with my believe of sincere communication.
I'll never be Mother Teresa, but at least I'll do the best I can with what I feel
is right for me, trying to focus on my strength and talent to make others picking
their brain and wonder about themselves. Being there for others will make you feel
less alone, less "on a road to nowhere". What do you have to lose?&lt;br&gt;
&lt;br&gt;
&lt;li&gt;
&lt;strong&gt;Is there a way for you to help others?&lt;br&gt;
&lt;/strong&gt;Do you feel lucky? If you do, you played your cards right somehow. Is there
a way for you to show your tricks to the world? to make others think of a different
way to look at things? Helping others makes a great closure between making others
proud and making you feel as a good person. It's a powerful tool you should use wisely.
The purpose is not the "convert" someone into your believes or trying to bring him
into your "group". One should reach his own right and wrong, you can only help him
by asking the right questions and trying to share your thoughts and experience. This
way you are part of the journey, part of a legacy in other's life. This is a great
accomplishment to leave behind you.&lt;br&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;
The order of the questions is important. Without making others proud and have their
support it's impossible to be highly motivated all the time. Without constant motivation
you won't allow yourself to grow into the person you can become, making it easier
to avoid helping others and seeking for the "wrong kind" of acceptance. &lt;strong&gt;Giving
up is easy, fitting in just for the sake of acceptance will not make you happier (at
least for long).&lt;/strong&gt;
&lt;br&gt;
&lt;br&gt;
Don't allow yourself to give up just because you were born to the wrong environment,
that you had troubles as a child or you feel just like the world is against you. The
world don't owe you anything, you can blame your luck, your God (or lack of it) but
bottom line it's really up to you. Don't hurt others to pay back to your awful sense
of luck. Find your positive people around you and let them pick you up when needed,
there is no shame of needing others help, they would love to do so in order to feel
good about themselves and making others proud. You'll do the same for them one day,
I promise you that.&lt;br&gt;
&lt;br&gt;
Everyone who knows me are familiar with my reiterative phrase "I firmly believe in
natural growth", this rule apply here as well. Find your own sources of strength and
make sure that you keep your "good standards" before trying to influence others to
ponder about their path in life. Once you have the confidence in your answers, you'll
be ready to open your view to the world and see what it has to offer.
&lt;/p&gt;
&lt;p&gt;
&lt;br&gt;
&lt;strong&gt;Do I believe in God?&lt;br&gt;
&lt;/strong&gt;We're probably ants in a giants world, but is it really matter? I would like
to think that this God cares more about us as living being, trying to grow together
than following strict rules without understanding the real truth behind them. Isn't
this the all purpose of the bible? of the stories we are taught since we were born?
I wish our discussions would address more of the "are we doing the best we can?" and
"how can we make it better?" rather than such a superficial scratch of our real purpose.
&lt;/p&gt;
&lt;p&gt;
I would love to hear what is &lt;strong&gt;your truth &lt;/strong&gt;and which questions drive
you in your path&lt;strong&gt;. &lt;/strong&gt;Drop me a comment if you feel like sharing.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://lnbogen.com/aggbug.ashx?id=8b187d37-d165-4882-8714-8e98e082ae55" /&gt;</description>
      <comments>http://lnbogen.com/CommentView,guid,8b187d37-d165-4882-8714-8e98e082ae55.aspx</comments>
    </item>
    <item>
      <trackback:ping>http://lnbogen.com/Trackback.aspx?guid=ca0ad2ad-5aac-4d9e-8ab8-3f76f9c2146e</trackback:ping>
      <pingback:server>http://lnbogen.com/pingback.aspx</pingback:server>
      <pingback:target>http://lnbogen.com/PermaLink,guid,ca0ad2ad-5aac-4d9e-8ab8-3f76f9c2146e.aspx</pingback:target>
      <dc:creator>Oren Ellenbogen</dc:creator>
      <wfw:comment>http://lnbogen.com/CommentView,guid,ca0ad2ad-5aac-4d9e-8ab8-3f76f9c2146e.aspx</wfw:comment>
      <wfw:commentRss>http://lnbogen.com/SyndicationService.asmx/GetEntryCommentsRss?guid=ca0ad2ad-5aac-4d9e-8ab8-3f76f9c2146e</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
          <a href="http://ripper234.com/">Ron</a> challenged me to write my own implementation
of <a href="http://en.wikipedia.org/wiki/Readers-writer_lock">reader/writers lock</a>.
He did a great job of doing <a href="http://ripper234.com/p/playing-with-a-few-readerwriterlocks-in-net/">his
own</a> implementation. 
</p>
        <p>
I came up with this:<br /><em>(note: this is really naive implementation, it's far from ideal in terms of fairness
and possible racing conditions. Just take it as brain-teaser)</em></p>
        <blockquote>
          <div style="border-right: gray 1px solid; padding-right: 4px; border-top: gray 1px solid; padding-left: 4px; font-size: 8pt; padding-bottom: 4px; margin: 20px 0px 10px; overflow: auto; border-left: gray 1px solid; width: 79.38%; cursor: text; max-height: 200px; line-height: 12pt; padding-top: 4px; border-bottom: gray 1px solid; font-family: consolas, 'Courier New', courier, monospace; height: 270px; background-color: #f4f4f4">
            <div style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
              <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none">
                <span style="color: #606060"> 1:</span>
                <span style="color: #0000ff">public</span>
                <span style="color: #0000ff">class</span> StateReaderWriterLock
: IDisposable</pre>
              <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
                <span style="color: #606060"> 2:</span> {</pre>
              <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none">
                <span style="color: #606060"> 3:</span>
                <span style="color: #0000ff">private</span>
                <span style="color: #0000ff">readonly</span> AutoResetEvent
_changeStateAutoLock = <span style="color: #0000ff">new</span> AutoResetEvent(<span style="color: #0000ff">false</span>);</pre>
              <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
                <span style="color: #606060"> 4:</span>
                <span style="color: #0000ff">private</span>
                <span style="color: #0000ff">readonly</span> AutoResetEvent
_writerDone = <span style="color: #0000ff">new</span> AutoResetEvent(<span style="color: #0000ff">false</span>);</pre>
              <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none">
                <span style="color: #606060"> 5:</span>
                <span style="color: #0000ff">private</span>
                <span style="color: #0000ff">readonly</span>
                <span style="color: #0000ff">object</span> _readersLock
= <span style="color: #0000ff">new</span><span style="color: #0000ff">object</span>();</pre>
              <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
                <span style="color: #606060"> 6:</span>
                <span style="color: #0000ff">private</span>
                <span style="color: #0000ff">readonly</span>
                <span style="color: #0000ff">object</span> _writersLock
= <span style="color: #0000ff">new</span><span style="color: #0000ff">object</span>();</pre>
              <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none">
                <span style="color: #606060"> 7:</span>
                <span style="color: #0000ff">private</span>
                <span style="color: #0000ff">int</span> _readers;</pre>
              <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
                <span style="color: #606060"> 8:</span>
                <span style="color: #0000ff">private</span>
                <span style="color: #0000ff">int</span> _state; <span style="color: #008000">//
0 is "neutral", 1 is read, 2 is write</span></pre>
              <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none">
                <span style="color: #606060"> 9:</span>
                <span style="color: #0000ff">private</span>
                <span style="color: #0000ff">int</span> _writers; </pre>
              <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
                <span style="color: #606060"> 10:</span>  </pre>
              <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none">
                <span style="color: #606060"> 11:</span>
                <span style="color: #0000ff">public</span>
                <span style="color: #0000ff">void</span> LockReader()</pre>
              <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
                <span style="color: #606060"> 12:</span> {</pre>
              <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none">
                <span style="color: #606060"> 13:</span>
                <span style="color: #0000ff">while</span> (<span style="color: #0000ff">true</span>)</pre>
              <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
                <span style="color: #606060"> 14:</span> {</pre>
              <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none">
                <span style="color: #606060"> 15:</span>
                <span style="color: #008000">//
try to bring the state from "neutral" or "read" to "read". If the current state is
"write", let's wait.</span>
              </pre>
              <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
                <span style="color: #606060"> 16:</span>
                <span style="color: #0000ff">while</span> (Interlocked.CompareExchange(<span style="color: #0000ff">ref</span> _state,
1, 0) == 2)</pre>
              <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none">
                <span style="color: #606060"> 17:</span> _changeStateAutoLock.WaitOne(); </pre>
              <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
                <span style="color: #606060"> 18:</span>  </pre>
              <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none">
                <span style="color: #606060"> 19:</span>
                <span style="color: #008000">//
an interesting case here where the last reader is now in ReleaseRead and we're trying
to read as well, we might be too late (the writer might have changed the _state already)</span>
              </pre>
              <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
                <span style="color: #606060"> 20:</span>
                <span style="color: #008000">//
if that happens - we're back to square one, but we still want to avoid recursive locking!</span>
              </pre>
              <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none">
                <span style="color: #606060"> 21:</span>
                <span style="color: #0000ff">bool</span> loseInRace
= <span style="color: #0000ff">false</span>;</pre>
              <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
                <span style="color: #606060"> 22:</span>
                <span style="color: #0000ff">lock</span> (_readersLock)</pre>
              <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none">
                <span style="color: #606060"> 23:</span> {</pre>
              <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
                <span style="color: #606060"> 24:</span>
                <span style="color: #0000ff">if</span> (Interlocked.CompareExchange(<span style="color: #0000ff">ref</span> _state,
1, 0) == 2)</pre>
              <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none">
                <span style="color: #606060"> 25:</span> loseInRace
= <span style="color: #0000ff">true</span>;</pre>
              <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
                <span style="color: #606060"> 26:</span>
                <span style="color: #0000ff">else</span>
              </pre>
              <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none">
                <span style="color: #606060"> 27:</span> _readers++;</pre>
              <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
                <span style="color: #606060"> 28:</span> }</pre>
              <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none">
                <span style="color: #606060"> 29:</span>
                <span style="color: #0000ff">if</span> (!loseInRace)</pre>
              <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
                <span style="color: #606060"> 30:</span>
                <span style="color: #0000ff">return</span>; <span style="color: #008000">//
success!</span></pre>
              <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none">
                <span style="color: #606060"> 31:</span> }</pre>
              <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
                <span style="color: #606060"> 32:</span> } </pre>
              <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none">
                <span style="color: #606060"> 33:</span>  </pre>
              <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
                <span style="color: #606060"> 34:</span>
                <span style="color: #0000ff">public</span>
                <span style="color: #0000ff">void</span> ReleaseReader()</pre>
              <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none">
                <span style="color: #606060"> 35:</span> {</pre>
              <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
                <span style="color: #606060"> 36:</span>
                <span style="color: #0000ff">lock</span> (_readersLock)</pre>
              <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none">
                <span style="color: #606060"> 37:</span> {</pre>
              <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
                <span style="color: #606060"> 38:</span> _readers--; </pre>
              <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none">
                <span style="color: #606060"> 39:</span>  </pre>
              <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
                <span style="color: #606060"> 40:</span>
                <span style="color: #008000">//
if I am the last reader, let's reset the state so any given reader/writer can take
it</span>
              </pre>
              <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none">
                <span style="color: #606060"> 41:</span>
                <span style="color: #0000ff">if</span> (_readers
== 0)</pre>
              <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
                <span style="color: #606060"> 42:</span> {</pre>
              <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none">
                <span style="color: #606060"> 43:</span> Thread.VolatileWrite(<span style="color: #0000ff">ref</span> _state,
0);</pre>
              <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
                <span style="color: #606060"> 44:</span> _changeStateAutoLock.Set();</pre>
              <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none">
                <span style="color: #606060"> 45:</span> }</pre>
              <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
                <span style="color: #606060"> 46:</span> }</pre>
              <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none">
                <span style="color: #606060"> 47:</span> } </pre>
              <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
                <span style="color: #606060"> 48:</span>  </pre>
              <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none">
                <span style="color: #606060"> 49:</span>
                <span style="color: #0000ff">public</span>
                <span style="color: #0000ff">void</span> LockWriter()</pre>
              <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
                <span style="color: #606060"> 50:</span> {</pre>
              <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none">
                <span style="color: #606060"> 51:</span>
                <span style="color: #0000ff">while</span> (<span style="color: #0000ff">true</span>)</pre>
              <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
                <span style="color: #606060"> 52:</span> {</pre>
              <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none">
                <span style="color: #606060"> 53:</span>
                <span style="color: #008000">//
try to bring the state from "neutral" or "write" to "write". If the current state
is "read", let's wait.</span>
              </pre>
              <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
                <span style="color: #606060"> 54:</span>
                <span style="color: #0000ff">while</span> (Interlocked.CompareExchange(<span style="color: #0000ff">ref</span> _state,
2, 0) == 1)</pre>
              <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none">
                <span style="color: #606060"> 55:</span> _changeStateAutoLock.WaitOne(); </pre>
              <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
                <span style="color: #606060"> 56:</span>  </pre>
              <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none">
                <span style="color: #606060"> 57:</span>
                <span style="color: #0000ff">bool</span> loseInRace
= <span style="color: #0000ff">false</span>;</pre>
              <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
                <span style="color: #606060"> 58:</span>
                <span style="color: #0000ff">lock</span> (_writersLock)</pre>
              <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none">
                <span style="color: #606060"> 59:</span> {</pre>
              <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
                <span style="color: #606060"> 60:</span>
                <span style="color: #0000ff">if</span> (Interlocked.CompareExchange(<span style="color: #0000ff">ref</span> _state,
2, 0) == 1)</pre>
              <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none">
                <span style="color: #606060"> 61:</span> loseInRace
= <span style="color: #0000ff">true</span>;</pre>
              <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
                <span style="color: #606060"> 62:</span>
                <span style="color: #0000ff">else</span>
              </pre>
              <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none">
                <span style="color: #606060"> 63:</span> _writers++;</pre>
              <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
                <span style="color: #606060"> 64:</span> } </pre>
              <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none">
                <span style="color: #606060"> 65:</span>  </pre>
              <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
                <span style="color: #606060"> 66:</span>
                <span style="color: #0000ff">if</span> (!loseInRace)</pre>
              <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none">
                <span style="color: #606060"> 67:</span>
                <span style="color: #0000ff">break</span>; <span style="color: #008000">//
great success!</span></pre>
              <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
                <span style="color: #606060"> 68:</span> } </pre>
              <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none">
                <span style="color: #606060"> 69:</span>  </pre>
              <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
                <span style="color: #606060"> 70:</span>
                <span style="color: #008000">//
allow 1 writer only</span>
              </pre>
              <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none">
                <span style="color: #606060"> 71:</span>
                <span style="color: #0000ff">if</span> (Thread.VolatileRead(<span style="color: #0000ff">ref</span> _writers)
&gt; 1)</pre>
              <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
                <span style="color: #606060"> 72:</span> {</pre>
              <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none">
                <span style="color: #606060"> 73:</span> _writerDone.WaitOne();</pre>
              <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
                <span style="color: #606060"> 74:</span> }</pre>
              <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none">
                <span style="color: #606060"> 75:</span> } </pre>
              <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
                <span style="color: #606060"> 76:</span>  </pre>
              <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none">
                <span style="color: #606060"> 77:</span>
                <span style="color: #0000ff">public</span>
                <span style="color: #0000ff">void</span> ReleaseWriter()</pre>
              <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
                <span style="color: #606060"> 78:</span> {</pre>
              <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none">
                <span style="color: #606060"> 79:</span>
                <span style="color: #0000ff">lock</span> (_writersLock)</pre>
              <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
                <span style="color: #606060"> 80:</span> {</pre>
              <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none">
                <span style="color: #606060"> 81:</span> _writers--; </pre>
              <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
                <span style="color: #606060"> 82:</span>  </pre>
              <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none">
                <span style="color: #606060"> 83:</span>
                <span style="color: #008000">//
if I am the last writer, let's reset the state so any given reader/writer can take
it</span>
              </pre>
              <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
                <span style="color: #606060"> 84:</span>
                <span style="color: #0000ff">if</span> (_writers
== 0)</pre>
              <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none">
                <span style="color: #606060"> 85:</span> {</pre>
              <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
                <span style="color: #606060"> 86:</span> Thread.VolatileWrite(<span style="color: #0000ff">ref</span> _state,
0);</pre>
              <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none">
                <span style="color: #606060"> 87:</span> _changeStateAutoLock.Set();</pre>
              <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
                <span style="color: #606060"> 88:</span> }</pre>
              <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none">
                <span style="color: #606060"> 89:</span>
                <span style="color: #0000ff">else</span>
              </pre>
              <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
                <span style="color: #606060"> 90:</span> {</pre>
              <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none">
                <span style="color: #606060"> 91:</span> _writerDone.Set();</pre>
              <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
                <span style="color: #606060"> 92:</span> }</pre>
              <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none">
                <span style="color: #606060"> 93:</span> }</pre>
              <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
                <span style="color: #606060"> 94:</span> } </pre>
              <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none">
                <span style="color: #606060"> 95:</span>  </pre>
              <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
                <span style="color: #606060"> 96:</span>
                <span style="color: #0000ff">public</span>
                <span style="color: #0000ff">void</span> Dispose()</pre>
              <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none">
                <span style="color: #606060"> 97:</span> {</pre>
              <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
                <span style="color: #606060"> 98:</span> _changeStateAutoLock.Close();</pre>
              <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none">
                <span style="color: #606060"> 99:</span> _writerDone.Close();</pre>
              <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
                <span style="color: #606060"> 100:</span> }</pre>
              <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none">
                <span style="color: #606060"> 101:</span> }</pre>
              <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
                <span style="color: #606060"> 102:</span>  </pre>
            </div>
          </div>
        </blockquote>
        <p>
          <br />
Not sure it's the greatest job interview question, but it is indeed challenging and
fun to play with.
</p>
        <img width="0" height="0" src="http://lnbogen.com/aggbug.ashx?id=ca0ad2ad-5aac-4d9e-8ab8-3f76f9c2146e" />
      </body>
      <title>ReaderWriterLock, my naive implementation</title>
      <guid isPermaLink="false">http://lnbogen.com/PermaLink,guid,ca0ad2ad-5aac-4d9e-8ab8-3f76f9c2146e.aspx</guid>
      <link>http://lnbogen.com/2009/01/28/ReaderWriterLockMyNaiveImplementation.aspx</link>
      <pubDate>Wed, 28 Jan 2009 11:20:02 GMT</pubDate>
      <description>&lt;p&gt;
&lt;a href="http://ripper234.com/"&gt;Ron&lt;/a&gt; challenged me to write my own implementation
of &lt;a href="http://en.wikipedia.org/wiki/Readers-writer_lock"&gt;reader/writers lock&lt;/a&gt;.
He did a great job of doing &lt;a href="http://ripper234.com/p/playing-with-a-few-readerwriterlocks-in-net/"&gt;his
own&lt;/a&gt; implementation. 
&lt;/p&gt;
&lt;p&gt;
I came up with this:&lt;br&gt;
&lt;em&gt;(note: this is really naive implementation, it's far from ideal in terms of fairness
and possible racing conditions. Just take it as brain-teaser)&lt;/em&gt;
&lt;/p&gt;
&lt;blockquote&gt; 
&lt;div style="border-right: gray 1px solid; padding-right: 4px; border-top: gray 1px solid; padding-left: 4px; font-size: 8pt; padding-bottom: 4px; margin: 20px 0px 10px; overflow: auto; border-left: gray 1px solid; width: 79.38%; cursor: text; max-height: 200px; line-height: 12pt; padding-top: 4px; border-bottom: gray 1px solid; font-family: consolas, 'Courier New', courier, monospace; height: 270px; background-color: #f4f4f4"&gt;
&lt;div style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 1:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;class&lt;/span&gt; StateReaderWriterLock
: IDisposable&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 2:&lt;/span&gt; {&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 3:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;private&lt;/span&gt; &lt;span style="color: #0000ff"&gt;readonly&lt;/span&gt; AutoResetEvent
_changeStateAutoLock = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; AutoResetEvent(&lt;span style="color: #0000ff"&gt;false&lt;/span&gt;);&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 4:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;private&lt;/span&gt; &lt;span style="color: #0000ff"&gt;readonly&lt;/span&gt; AutoResetEvent
_writerDone = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; AutoResetEvent(&lt;span style="color: #0000ff"&gt;false&lt;/span&gt;);&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 5:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;private&lt;/span&gt; &lt;span style="color: #0000ff"&gt;readonly&lt;/span&gt; &lt;span style="color: #0000ff"&gt;object&lt;/span&gt; _readersLock
= &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; &lt;span style="color: #0000ff"&gt;object&lt;/span&gt;();&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 6:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;private&lt;/span&gt; &lt;span style="color: #0000ff"&gt;readonly&lt;/span&gt; &lt;span style="color: #0000ff"&gt;object&lt;/span&gt; _writersLock
= &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; &lt;span style="color: #0000ff"&gt;object&lt;/span&gt;();&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 7:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;private&lt;/span&gt; &lt;span style="color: #0000ff"&gt;int&lt;/span&gt; _readers;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 8:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;private&lt;/span&gt; &lt;span style="color: #0000ff"&gt;int&lt;/span&gt; _state; &lt;span style="color: #008000"&gt;//
0 is "neutral", 1 is read, 2 is write&lt;/span&gt;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 9:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;private&lt;/span&gt; &lt;span style="color: #0000ff"&gt;int&lt;/span&gt; _writers; &lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 10:&lt;/span&gt;&amp;nbsp; &lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 11:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; LockReader()&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 12:&lt;/span&gt; {&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 13:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;while&lt;/span&gt; (&lt;span style="color: #0000ff"&gt;true&lt;/span&gt;)&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 14:&lt;/span&gt; {&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 15:&lt;/span&gt; &lt;span style="color: #008000"&gt;//
try to bring the state from "neutral" or "read" to "read". If the current state is
"write", let's wait.&lt;/span&gt;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 16:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;while&lt;/span&gt; (Interlocked.CompareExchange(&lt;span style="color: #0000ff"&gt;ref&lt;/span&gt; _state,
1, 0) == 2)&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 17:&lt;/span&gt; _changeStateAutoLock.WaitOne(); &lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 18:&lt;/span&gt;&amp;nbsp; &lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 19:&lt;/span&gt; &lt;span style="color: #008000"&gt;//
an interesting case here where the last reader is now in ReleaseRead and we're trying
to read as well, we might be too late (the writer might have changed the _state already)&lt;/span&gt;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 20:&lt;/span&gt; &lt;span style="color: #008000"&gt;//
if that happens - we're back to square one, but we still want to avoid recursive locking!&lt;/span&gt;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 21:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;bool&lt;/span&gt; loseInRace
= &lt;span style="color: #0000ff"&gt;false&lt;/span&gt;;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 22:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;lock&lt;/span&gt; (_readersLock)&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 23:&lt;/span&gt; {&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 24:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (Interlocked.CompareExchange(&lt;span style="color: #0000ff"&gt;ref&lt;/span&gt; _state,
1, 0) == 2)&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 25:&lt;/span&gt; loseInRace
= &lt;span style="color: #0000ff"&gt;true&lt;/span&gt;;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 26:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;else&lt;/span&gt;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 27:&lt;/span&gt; _readers++;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 28:&lt;/span&gt; }&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 29:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (!loseInRace)&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 30:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;return&lt;/span&gt;; &lt;span style="color: #008000"&gt;//
success!&lt;/span&gt;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 31:&lt;/span&gt; }&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 32:&lt;/span&gt; } &lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 33:&lt;/span&gt;&amp;nbsp; &lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 34:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; ReleaseReader()&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 35:&lt;/span&gt; {&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 36:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;lock&lt;/span&gt; (_readersLock)&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 37:&lt;/span&gt; {&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 38:&lt;/span&gt; _readers--; &lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 39:&lt;/span&gt;&amp;nbsp; &lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 40:&lt;/span&gt; &lt;span style="color: #008000"&gt;//
if I am the last reader, let's reset the state so any given reader/writer can take
it&lt;/span&gt;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 41:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (_readers
== 0)&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 42:&lt;/span&gt; {&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 43:&lt;/span&gt; Thread.VolatileWrite(&lt;span style="color: #0000ff"&gt;ref&lt;/span&gt; _state,
0);&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 44:&lt;/span&gt; _changeStateAutoLock.Set();&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 45:&lt;/span&gt; }&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 46:&lt;/span&gt; }&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 47:&lt;/span&gt; } &lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 48:&lt;/span&gt;&amp;nbsp; &lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 49:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; LockWriter()&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 50:&lt;/span&gt; {&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 51:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;while&lt;/span&gt; (&lt;span style="color: #0000ff"&gt;true&lt;/span&gt;)&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 52:&lt;/span&gt; {&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 53:&lt;/span&gt; &lt;span style="color: #008000"&gt;//
try to bring the state from "neutral" or "write" to "write". If the current state
is "read", let's wait.&lt;/span&gt;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 54:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;while&lt;/span&gt; (Interlocked.CompareExchange(&lt;span style="color: #0000ff"&gt;ref&lt;/span&gt; _state,
2, 0) == 1)&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 55:&lt;/span&gt; _changeStateAutoLock.WaitOne(); &lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 56:&lt;/span&gt;&amp;nbsp; &lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 57:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;bool&lt;/span&gt; loseInRace
= &lt;span style="color: #0000ff"&gt;false&lt;/span&gt;;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 58:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;lock&lt;/span&gt; (_writersLock)&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 59:&lt;/span&gt; {&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 60:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (Interlocked.CompareExchange(&lt;span style="color: #0000ff"&gt;ref&lt;/span&gt; _state,
2, 0) == 1)&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 61:&lt;/span&gt; loseInRace
= &lt;span style="color: #0000ff"&gt;true&lt;/span&gt;;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 62:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;else&lt;/span&gt;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 63:&lt;/span&gt; _writers++;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 64:&lt;/span&gt; } &lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 65:&lt;/span&gt;&amp;nbsp; &lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 66:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (!loseInRace)&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 67:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;break&lt;/span&gt;; &lt;span style="color: #008000"&gt;//
great success!&lt;/span&gt;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 68:&lt;/span&gt; } &lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 69:&lt;/span&gt;&amp;nbsp; &lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 70:&lt;/span&gt; &lt;span style="color: #008000"&gt;//
allow 1 writer only&lt;/span&gt;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 71:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (Thread.VolatileRead(&lt;span style="color: #0000ff"&gt;ref&lt;/span&gt; _writers)
&amp;gt; 1)&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 72:&lt;/span&gt; {&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 73:&lt;/span&gt; _writerDone.WaitOne();&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 74:&lt;/span&gt; }&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 75:&lt;/span&gt; } &lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 76:&lt;/span&gt;&amp;nbsp; &lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 77:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; ReleaseWriter()&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 78:&lt;/span&gt; {&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 79:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;lock&lt;/span&gt; (_writersLock)&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 80:&lt;/span&gt; {&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 81:&lt;/span&gt; _writers--; &lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 82:&lt;/span&gt;&amp;nbsp; &lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 83:&lt;/span&gt; &lt;span style="color: #008000"&gt;//
if I am the last writer, let's reset the state so any given reader/writer can take
it&lt;/span&gt;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 84:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (_writers
== 0)&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 85:&lt;/span&gt; {&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 86:&lt;/span&gt; Thread.VolatileWrite(&lt;span style="color: #0000ff"&gt;ref&lt;/span&gt; _state,
0);&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 87:&lt;/span&gt; _changeStateAutoLock.Set();&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 88:&lt;/span&gt; }&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 89:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;else&lt;/span&gt;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 90:&lt;/span&gt; {&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 91:&lt;/span&gt; _writerDone.Set();&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 92:&lt;/span&gt; }&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 93:&lt;/span&gt; }&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 94:&lt;/span&gt; } &lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 95:&lt;/span&gt;&amp;nbsp; &lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 96:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; Dispose()&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 97:&lt;/span&gt; {&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 98:&lt;/span&gt; _changeStateAutoLock.Close();&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 99:&lt;/span&gt; _writerDone.Close();&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 100:&lt;/span&gt; }&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 101:&lt;/span&gt; }&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 102:&lt;/span&gt;&amp;nbsp; &lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/blockquote&gt; 
&lt;p&gt;
&lt;br&gt;
Not sure it's the greatest job interview question, but it is indeed challenging and
fun to play with.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://lnbogen.com/aggbug.ashx?id=ca0ad2ad-5aac-4d9e-8ab8-3f76f9c2146e" /&gt;</description>
      <comments>http://lnbogen.com/CommentView,guid,ca0ad2ad-5aac-4d9e-8ab8-3f76f9c2146e.aspx</comments>
    </item>
    <item>
      <trackback:ping>http://lnbogen.com/Trackback.aspx?guid=4a080d3e-b807-49b0-b891-e08306db73ab</trackback:ping>
      <pingback:server>http://lnbogen.com/pingback.aspx</pingback:server>
      <pingback:target>http://lnbogen.com/PermaLink,guid,4a080d3e-b807-49b0-b891-e08306db73ab.aspx</pingback:target>
      <dc:creator>Oren Ellenbogen</dc:creator>
      <wfw:comment>http://lnbogen.com/CommentView,guid,4a080d3e-b807-49b0-b891-e08306db73ab.aspx</wfw:comment>
      <wfw:commentRss>http://lnbogen.com/SyndicationService.asmx/GetEntryCommentsRss?guid=4a080d3e-b807-49b0-b891-e08306db73ab</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
Imagine you've got the following code, running in 2 separate threads T1 and T2:
</p>
        <blockquote>
          <p>
private bool _go = true;
</p>
        </blockquote>
        <blockquote>
          <p>
T1                                     
T2<br />
while (_go)                       
// ... some code here ...<br />
{                                        
_go = false; // something happened, let's stop<br />
   // ... do work<br />
}
</p>
        </blockquote>
        <p>
Even if T2 will set _<em>go</em> to false, this code might lead to endless loop in
T1. Why is that? 
<br />
Each CPU have a local memory called <a href="http://en.wikipedia.org/wiki/CPU_cache">L1
Cache</a>, that might cache the value of _<em>go. </em>Multiple threads running on
multiple CPU's can (and will) cache data and re-order instructions to optimize code.
So if for example, T1 is running on processorA and T2 is running on processorB, we
might have an endless loop here. A simple solution here is to add the <a href="http://msdn.microsoft.com/en-us/library/x13ttww7(VS.71).aspx">volatile
keyword</a> on the <em>_go</em> field definition to assure order and avoid caching
on CPU level:
</p>
        <blockquote>
          <p>
            <em>"The <b>volatile</b> modifier is usually used for a field that is accessed by
multiple threads without using the </em>
            <a href="http://msdn.microsoft.com/en-us/library/c5kehkcz(VS.71).aspx">
              <em>lock</em>
            </a>
            <em> statement
to serialize access. Using the <b>volatile</b> modifier ensures that one thread retrieves
the most up-to-date value written by another thread." (MSDN)</em>
          </p>
        </blockquote>
        <p>
          <br />
Now let's examine another example, again 2 threads T1 and T2:
</p>
        <blockquote>
          <p>
private int _writers = 0;
</p>
        </blockquote>
        <blockquote>
          <p>
T1                                                        
T2<br />
while (_writers &gt; 1)                             
....<br />
{                                                          
Interlocked.Increment(ref _writers);<br />
    _someAutoEvent.WaitOne();<br />
}
</p>
        </blockquote>
        <p>
You can see that we're using an <strong>atomic increment</strong> via Interlocked.Increment
method, so we should be thread-safe here right? not quite. 
<br />
We've got one thread that is <strong>reading </strong>(T1) and another thread that
is <strong>writing </strong>(T2) to <em>_writers</em>. If T1 is running in processorA
and T2 in processorB, the <em>_writers</em> value will be cached on the CPU level
for some time which means T1 might see <strong>different value</strong> than T2. If
T2 would have catch the returned value from Interlocked.Increment and it as the <strong>only
reader</strong> of that field, then it was thread-safe. This is not the case here. 
<br />
The solution here is to use Thread.VolatileRead(ref _writers) to make sure T1 gets
the latest value. We could have used <em><a href="http://msdn.microsoft.com/en-us/library/c5kehkcz(VS.80).aspx">lock
keyword</a></em> as well of course to serialize access to _writers field.
</p>
        <p>
          <br />
Summary:
</p>
        <ul>
          <li>
Although setting a word size variable is atomic (like in our first example), it doesn't
mean it is thread-safe! For "boolean flags" I would recommend using <em>volatile</em> as
a clean and simple solution.</li>
          <li>
For "counters scenarios", I would have used Interlocked with Thread.ReadVolatile.
This should outperform <em>lock </em>usage and still keep your code neat and shiny.</li>
          <li>
The <em>lock keyword</em> is probably the safest way to avoid dangerous race conditions,
so unless you're sure about your solution, keep it simple and use <em>lock</em>.</li>
        </ul>
        <img width="0" height="0" src="http://lnbogen.com/aggbug.ashx?id=4a080d3e-b807-49b0-b891-e08306db73ab" />
      </body>
      <title>On Interlocked.Increment and volatile</title>
      <guid isPermaLink="false">http://lnbogen.com/PermaLink,guid,4a080d3e-b807-49b0-b891-e08306db73ab.aspx</guid>
      <link>http://lnbogen.com/2009/01/28/OnInterlockedIncrementAndVolatile.aspx</link>
      <pubDate>Wed, 28 Jan 2009 10:31:52 GMT</pubDate>
      <description>&lt;p&gt;
Imagine you've got the following code, running in 2 separate threads T1 and T2:
&lt;/p&gt;
&lt;blockquote&gt; 
&lt;p&gt;
private bool _go = true;
&lt;/p&gt;
&lt;/blockquote&gt; &lt;blockquote&gt; 
&lt;p&gt;
T1&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
T2&lt;br&gt;
while (_go)&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
// ... some code here ...&lt;br&gt;
{&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
_go = false; // something happened, let's stop&lt;br&gt;
&amp;nbsp;&amp;nbsp; // ... do work&lt;br&gt;
}
&lt;/p&gt;
&lt;/blockquote&gt; 
&lt;p&gt;
Even if T2 will set _&lt;em&gt;go&lt;/em&gt; to false, this code might lead to endless loop in
T1. Why is that? 
&lt;br&gt;
Each CPU have a local memory called &lt;a href="http://en.wikipedia.org/wiki/CPU_cache"&gt;L1
Cache&lt;/a&gt;, that might cache the value of _&lt;em&gt;go. &lt;/em&gt;Multiple threads running on
multiple CPU's can (and will) cache data and re-order instructions to optimize code.
So if for example, T1 is running on processorA and T2 is running on processorB, we
might have an endless loop here. A simple solution here is to add the &lt;a href="http://msdn.microsoft.com/en-us/library/x13ttww7(VS.71).aspx"&gt;volatile
keyword&lt;/a&gt; on the &lt;em&gt;_go&lt;/em&gt; field definition to assure order and avoid caching
on CPU level:
&lt;/p&gt;
&lt;blockquote&gt; 
&lt;p&gt;
&lt;em&gt;"The &lt;b&gt;volatile&lt;/b&gt; modifier is usually used for a field that is accessed by
multiple threads without using the &lt;/em&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/c5kehkcz(VS.71).aspx"&gt;&lt;em&gt;lock&lt;/em&gt;&lt;/a&gt;&lt;em&gt; statement
to serialize access. Using the &lt;b&gt;volatile&lt;/b&gt; modifier ensures that one thread retrieves
the most up-to-date value written by another thread." (MSDN)&lt;/em&gt;
&lt;/p&gt;
&lt;/blockquote&gt; 
&lt;p&gt;
&lt;br&gt;
Now let's examine another example, again 2 threads T1 and T2:
&lt;/p&gt;
&lt;blockquote&gt; 
&lt;p&gt;
private int _writers = 0;
&lt;/p&gt;
&lt;/blockquote&gt; &lt;blockquote&gt; 
&lt;p&gt;
T1&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
T2&lt;br&gt;
while (_writers &amp;gt; 1)&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
....&lt;br&gt;
{&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
Interlocked.Increment(ref _writers);&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; _someAutoEvent.WaitOne();&lt;br&gt;
}
&lt;/p&gt;
&lt;/blockquote&gt; 
&lt;p&gt;
You can see that we're using an &lt;strong&gt;atomic increment&lt;/strong&gt; via Interlocked.Increment
method, so we should be thread-safe here right? not quite. 
&lt;br&gt;
We've got one thread that is &lt;strong&gt;reading &lt;/strong&gt;(T1) and another thread that
is &lt;strong&gt;writing &lt;/strong&gt;(T2) to &lt;em&gt;_writers&lt;/em&gt;. If T1 is running in processorA
and T2 in processorB, the &lt;em&gt;_writers&lt;/em&gt; value will be cached on the CPU level
for some time which means T1 might see &lt;strong&gt;different value&lt;/strong&gt; than T2. If
T2 would have catch the returned value from Interlocked.Increment and it as the &lt;strong&gt;only
reader&lt;/strong&gt; of that field, then it was thread-safe. This is not the case here. 
&lt;br&gt;
The solution here is to use Thread.VolatileRead(ref _writers) to make sure T1 gets
the latest value. We could have used &lt;em&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/c5kehkcz(VS.80).aspx"&gt;lock
keyword&lt;/a&gt;&lt;/em&gt; as well of course to serialize access to _writers field.
&lt;/p&gt;
&lt;p&gt;
&lt;br&gt;
Summary:
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
Although setting a word size variable is atomic (like in our first example), it doesn't
mean it is thread-safe! For "boolean flags" I would recommend using &lt;em&gt;volatile&lt;/em&gt; as
a clean and simple solution.&lt;/li&gt;
&lt;li&gt;
For "counters scenarios", I would have used Interlocked with Thread.ReadVolatile.
This should outperform &lt;em&gt;lock &lt;/em&gt;usage and still keep your code neat and shiny.&lt;/li&gt;
&lt;li&gt;
The &lt;em&gt;lock keyword&lt;/em&gt; is probably the safest way to avoid dangerous race conditions,
so unless you're sure about your solution, keep it simple and use &lt;em&gt;lock&lt;/em&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;img width="0" height="0" src="http://lnbogen.com/aggbug.ashx?id=4a080d3e-b807-49b0-b891-e08306db73ab" /&gt;</description>
      <comments>http://lnbogen.com/CommentView,guid,4a080d3e-b807-49b0-b891-e08306db73ab.aspx</comments>
    </item>
    <item>
      <trackback:ping>http://lnbogen.com/Trackback.aspx?guid=940a4303-6d3b-46b3-82d4-dfd9ecf5996c</trackback:ping>
      <pingback:server>http://lnbogen.com/pingback.aspx</pingback:server>
      <pingback:target>http://lnbogen.com/PermaLink,guid,940a4303-6d3b-46b3-82d4-dfd9ecf5996c.aspx</pingback:target>
      <dc:creator>Oren Ellenbogen</dc:creator>
      <wfw:comment>http://lnbogen.com/CommentView,guid,940a4303-6d3b-46b3-82d4-dfd9ecf5996c.aspx</wfw:comment>
      <wfw:commentRss>http://lnbogen.com/SyndicationService.asmx/GetEntryCommentsRss?guid=940a4303-6d3b-46b3-82d4-dfd9ecf5996c</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
It seems that someone has upload a 10 minutes video for some time now (thanks TristanIce!). 
<br />
This is far from being a well prepared lecture (<a href="http://altdotnet.org/">alt.net</a> is
all about "everyone can get up and talk"), I just tried to show the charm behind CCR
after people started to share their pain developing multi-threaded applications. I'm
talking crazy-fast and the material is not well organized so I had to think while
talking/writing. The results are hard to watch. Multi-threading is a bitch eh?<br /><br />
All in all, the vibe was positive and people looked intrigued by it. Anyway, here
it is:<br /><br /><a href="http://video.msn.com/video.aspx?mkt=en-us&amp;vid=3e5f4b8a-947b-46a0-9436-0d2f7cd4e488">Oren
explains how to use CCR framework</a> (MSN video, the movie is playing on the right)
</p>
        <p>
 
</p>
Makes me want to prepare a lecture on the subject some day...<img width="0" height="0" src="http://lnbogen.com/aggbug.ashx?id=940a4303-6d3b-46b3-82d4-dfd9ecf5996c" /></body>
      <title>Talking about Microsoft CCR on ALT.NET Israel</title>
      <guid isPermaLink="false">http://lnbogen.com/PermaLink,guid,940a4303-6d3b-46b3-82d4-dfd9ecf5996c.aspx</guid>
      <link>http://lnbogen.com/2008/12/30/TalkingAboutMicrosoftCCROnALTNETIsrael.aspx</link>
      <pubDate>Tue, 30 Dec 2008 19:29:41 GMT</pubDate>
      <description>&lt;p&gt;
It seems that someone has upload a 10 minutes video for some time now (thanks TristanIce!). 
&lt;br&gt;
This is far from being a well prepared lecture (&lt;a href="http://altdotnet.org/"&gt;alt.net&lt;/a&gt; is
all about "everyone can get up and talk"), I just tried to show the charm behind CCR
after people started to share their pain developing multi-threaded applications. I'm
talking crazy-fast and the material is not well organized so I had to think while
talking/writing. The results are hard to watch. Multi-threading is a bitch eh?&lt;br&gt;
&lt;br&gt;
All in all, the vibe was positive and people looked intrigued by it. Anyway, here
it is:&lt;br&gt;
&lt;br&gt;
&lt;a href="http://video.msn.com/video.aspx?mkt=en-us&amp;amp;vid=3e5f4b8a-947b-46a0-9436-0d2f7cd4e488"&gt;Oren
explains how to use CCR framework&lt;/a&gt; (MSN video, the movie is playing on the right)
&lt;/p&gt;
&lt;p&gt;
&amp;nbsp;
&lt;/p&gt;
Makes me want to prepare a lecture on the subject some day...&lt;img width="0" height="0" src="http://lnbogen.com/aggbug.ashx?id=940a4303-6d3b-46b3-82d4-dfd9ecf5996c" /&gt;</description>
      <comments>http://lnbogen.com/CommentView,guid,940a4303-6d3b-46b3-82d4-dfd9ecf5996c.aspx</comments>
    </item>
    <item>
      <trackback:ping>http://lnbogen.com/Trackback.aspx?guid=4d6edfa8-c3a5-4aca-b34a-d597be0095a9</trackback:ping>
      <pingback:server>http://lnbogen.com/pingback.aspx</pingback:server>
      <pingback:target>http://lnbogen.com/PermaLink,guid,4d6edfa8-c3a5-4aca-b34a-d597be0095a9.aspx</pingback:target>
      <dc:creator>Oren Ellenbogen</dc:creator>
      <wfw:comment>http://lnbogen.com/CommentView,guid,4d6edfa8-c3a5-4aca-b34a-d597be0095a9.aspx</wfw:comment>
      <wfw:commentRss>http://lnbogen.com/SyndicationService.asmx/GetEntryCommentsRss?guid=4d6edfa8-c3a5-4aca-b34a-d597be0095a9</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
Requirements:
</p>
        <ol>
          <li>
Be able to read all the lines in a given file. 
</li>
          <li>
Be able to do so even if the file is HUGE ( == don't load it all at once). 
</li>
          <li>
Control the number of items I want to receive and whether or not the enumerator ignore
empty lines. Always nice to have. 
</li>
          <li>
Thread-safe should be supported easily. Think about 50 threads, each reading the next
line and processing it. 
</li>
          <li>
Nice performance is a plus.</li>
        </ol>
        <p>
          <br />
Playing with the API with my teammate <a href="http://ripper234.com/">Ron</a> gave
the following (code written in notepad, stupidity won't compile):
</p>
        <h4>"Common foreach" usage:
</h4>
        <p>
foreach (string line in FileStreamer.GetLines(@"c:\temp\myfile.txt", true, 1000))
{ /* .. code */ } // read 1000 items from the file while ignoring empty lines.
</p>
        <h4>
          <br />
Reading from multiple threads usage:
</h4>
        <p>
using (FileStreamer streamer = new FileStreamer(@"c:\temp\myfile.txt", true, -1))
// -1 means no limit, read all non-empty lines<br />
{<br />
    Thread[] threads = new Thread[10];<br />
    for(int i=0; i&lt;threads.Length; i++)<br />
    {<br />
        threads[i] = new Thread((ThreadStart)delegate
{ 
<br />
            string line;<br />
            if (!streamer.TryGetNextLine(out
line)) // thread safe!<br />
               
return; // end of file, we can exit<br /><br />
            // do work ...<br />
        }); 
</p>
        <p>
        threads[i].Start();<br />
    } 
</p>
        <p>
    // join the threads + whatever ...<br />
} 
</p>
        <p>
 
</p>
        <p>
After reading a few ideas in <a href="http://stackoverflow.com/questions/286533/filestream-streamreader-problem-in-c">stackoverflow</a>,
I thought to share my solution:     
</p>
        <div style="border-right: gray 1px solid; padding-right: 4px; border-top: gray 1px solid; padding-left: 4px; font-size: 8pt; padding-bottom: 4px; margin: 20px 0px 10px; overflow: auto; border-left: gray 1px solid; width: 97.5%; cursor: text; max-height: 200px; line-height: 12pt; padding-top: 4px; border-bottom: gray 1px solid; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4">
          <div style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none">
              <span style="color: #008000">//
written by bogen (30/12/2008)</span>
            </pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"> </pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none">
              <span style="color: #cc6633">#region</span>
              <span style="color: #0000ff">using</span>
            </pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"> </pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none">
              <span style="color: #0000ff">using</span> System;</pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
              <span style="color: #0000ff">using</span> System.Collections.Generic;</pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none">
              <span style="color: #0000ff">using</span> System.IO;</pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"> </pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none">
              <span style="color: #cc6633">#endregion</span>
            </pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"> </pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none">
              <span style="color: #0000ff">namespace</span> Semingo.Common.Utils</pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">{</pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none">
              <span style="color: #008000">///
&lt;summary&gt;</span>
            </pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
              <span style="color: #008000">///
Return a stream of lines for the specified file.</span>
            </pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none">
              <span style="color: #008000">///
This class is thread safe by design!</span>
            </pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
              <span style="color: #008000">///
Use the static method FileStreamer.GetLines for not thread safe usage (via foreach)</span>
            </pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none">
              <span style="color: #008000">///
&lt;/summary&gt;</span>
            </pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
              <span style="color: #0000ff">public</span>
              <span style="color: #0000ff">class</span> FileStreamer
: IDisposable</pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none">    {</pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
              <span style="color: #cc6633">#region</span> fields</pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"> </pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
              <span style="color: #0000ff">private</span>
              <span style="color: #0000ff">readonly</span>
              <span style="color: #0000ff">object</span> _locker
= <span style="color: #0000ff">new</span><span style="color: #0000ff">object</span>();</pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none">
              <span style="color: #0000ff">private</span>
              <span style="color: #0000ff">readonly</span>
              <span style="color: #0000ff">string</span> _path;</pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
              <span style="color: #0000ff">private</span>
              <span style="color: #0000ff">readonly</span>
              <span style="color: #0000ff">bool</span> _ignoreEmptyLines;</pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none">
              <span style="color: #0000ff">private</span>
              <span style="color: #0000ff">readonly</span>
              <span style="color: #0000ff">int</span> _limit;</pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
              <span style="color: #0000ff">private</span>
              <span style="color: #0000ff">readonly</span> IEnumerator&lt;<span style="color: #0000ff">string</span>&gt;
_enumerator;</pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none">
              <span style="color: #0000ff">private</span>
              <span style="color: #0000ff">int</span> _linesGiven;</pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
              <span style="color: #0000ff">private</span>
              <span style="color: #0000ff">bool</span> _disposed;</pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"> </pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
              <span style="color: #cc6633">#endregion</span>
            </pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"> </pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
              <span style="color: #cc6633">#region</span> ctors</pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"> </pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
              <span style="color: #008000">///
&lt;summary&gt;</span>
            </pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none">
              <span style="color: #008000">///
Create a file streamer instance</span>
            </pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
              <span style="color: #008000">///
&lt;/summary&gt;</span>
            </pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none">
              <span style="color: #008000">///
&lt;param name="path"&gt;File path&lt;/param&gt;</span>
            </pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
              <span style="color: #0000ff">public</span> FileStreamer(<span style="color: #0000ff">string</span> path)
: <span style="color: #0000ff">this</span>(path, <span style="color: #0000ff">false</span>,
-1)</pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none">        {</pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">        }</pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"> </pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
              <span style="color: #008000">///
&lt;summary&gt;</span>
            </pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none">
              <span style="color: #008000">///
Create a file streamer instance</span>
            </pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
              <span style="color: #008000">///
&lt;/summary&gt;</span>
            </pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none">
              <span style="color: #008000">///
&lt;param name="path"&gt;File path&lt;/param&gt;</span>
            </pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
              <span style="color: #008000">///
&lt;param name="ignoreEmptyLines"&gt;Should the streamer avoid empty lines&lt;/param&gt;</span>
            </pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none">
              <span style="color: #008000">///
&lt;param name="limit"&gt;Number of maximum lines the streamer should return. Send
-1 for no limit&lt;/param&gt;</span>
            </pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
              <span style="color: #0000ff">public</span> FileStreamer(<span style="color: #0000ff">string</span> path, <span style="color: #0000ff">bool</span> ignoreEmptyLines, <span style="color: #0000ff">int</span> limit)</pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none">        {</pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
              <span style="color: #0000ff">if</span> (!File.Exists(path))</pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none">
              <span style="color: #0000ff">throw</span>
              <span style="color: #0000ff">new</span> ArgumentException(<span style="color: #006080">"Cannot
find the file: "</span> + path);</pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
              <span style="color: #0000ff">if</span> (limit
!= -1 &amp;&amp; limit &lt;=0 )</pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none">
              <span style="color: #0000ff">throw</span>
              <span style="color: #0000ff">new</span> ArgumentException(<span style="color: #006080">"Limit
must be bigger than 0 (or -1 for no limit) but was: "</span> + limit + <span style="color: #006080">".
File given was: "</span> + path);</pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"> </pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none">            _path = path;</pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">            _ignoreEmptyLines = ignoreEmptyLines;</pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none">            _limit = limit;</pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
            </pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none">            _enumerator = CreateStream().GetEnumerator();</pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">        }</pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"> </pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
              <span style="color: #cc6633">#endregion</span>
            </pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"> </pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
              <span style="color: #cc6633">#region</span>
              <span style="color: #0000ff">public</span> API</pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"> </pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
              <span style="color: #0000ff">public</span>
              <span style="color: #0000ff">bool</span> TryGetNextLine(<span style="color: #0000ff">out</span><span style="color: #0000ff">string</span> nextItem)</pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none">        {</pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
              <span style="color: #0000ff">lock</span> (_locker)</pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none">            {</pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
              <span style="color: #0000ff">return</span> TryGetNextLineAssumingInsideLock(<span style="color: #0000ff">out</span> nextItem);</pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none">            }</pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">        }</pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"> </pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
              <span style="color: #0000ff">public</span>
              <span style="color: #0000ff">bool</span> TryGetNextLines(<span style="color: #0000ff">out</span> ICollection&lt;<span style="color: #0000ff">string</span>&gt;
nextItems, <span style="color: #0000ff">int</span> howMany)</pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none">        {</pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
              <span style="color: #0000ff">if</span> (howMany
&lt;= 0)</pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none">
              <span style="color: #0000ff">throw</span>
              <span style="color: #0000ff">new</span> ArgumentException(<span style="color: #006080">"'howMany'
parameter must be &gt; 0 but was "</span> + howMany, <span style="color: #006080">"howMany"</span>);</pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"> </pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none">            nextItems = <span style="color: #0000ff">new</span> List&lt;<span style="color: #0000ff">string</span>&gt;(howMany);</pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
              <span style="color: #0000ff">lock</span> (_locker)</pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none">            {</pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
              <span style="color: #0000ff">string</span> nextItem;</pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none">
              <span style="color: #0000ff">for</span>(<span style="color: #0000ff">int</span> i=0;
i&lt;howMany; i++)</pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">                {</pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none">
              <span style="color: #0000ff">if</span> (!TryGetNextLineAssumingInsideLock(<span style="color: #0000ff">out</span> nextItem))</pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
              <span style="color: #0000ff">break</span>; <span style="color: #008000">//
no more lines (EOF)</span></pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none">
            </pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">                    nextItems.Add(nextItem);</pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none">                }</pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">            }</pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"> </pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
              <span style="color: #0000ff">return</span> nextItems.Count
&gt; 0;</pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none">        }</pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
            </pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none">
              <span style="color: #0000ff">public</span>
              <span style="color: #0000ff">static</span> IEnumerable&lt;<span style="color: #0000ff">string</span>&gt;
GetLines(<span style="color: #0000ff">string</span> path)</pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">        {</pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none">
              <span style="color: #0000ff">return</span> GetLines(path, <span style="color: #0000ff">false</span>,
-1);</pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">        }</pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"> </pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
              <span style="color: #008000">///
&lt;summary&gt;</span>
            </pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none">
              <span style="color: #008000">/// </span>
            </pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
              <span style="color: #008000">///
&lt;/summary&gt;</span>
            </pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none">
              <span style="color: #008000">///
&lt;param name="path"&gt;&lt;/param&gt;</span>
            </pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
              <span style="color: #008000">///
&lt;param name="ignoreEmptyLines"&gt;&lt;/param&gt;</span>
            </pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none">
              <span style="color: #008000">///
&lt;param name="limit"&gt;send -1 for no limit&lt;/param&gt;</span>
            </pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
              <span style="color: #008000">///
&lt;returns&gt;&lt;/returns&gt;</span>
            </pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none">
              <span style="color: #0000ff">public</span>
              <span style="color: #0000ff">static</span> IEnumerable&lt;<span style="color: #0000ff">string</span>&gt;
GetLines(<span style="color: #0000ff">string</span> path, <span style="color: #0000ff">bool</span> ignoreEmptyLines, <span style="color: #0000ff">int</span> limit)</pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">        {</pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none">
              <span style="color: #0000ff">using</span> (FileStreamer
streamer = <span style="color: #0000ff">new</span> FileStreamer(path, ignoreEmptyLines,
limit))</pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">            {</pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none">
              <span style="color: #0000ff">string</span> nextItem;</pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
              <span style="color: #0000ff">while</span> (streamer.TryGetNextLine(<span style="color: #0000ff">out</span> nextItem))</pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none">
              <span style="color: #0000ff">yield</span>
              <span style="color: #0000ff">return</span> nextItem;</pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"> </pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none">
              <span style="color: #0000ff">yield</span>
              <span style="color: #0000ff">break</span>; <span style="color: #008000">//
EOF</span></pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">            }</pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none">        }</pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"> </pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none">
              <span style="color: #008000">///&lt;summary&gt;</span>
            </pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
              <span style="color: #008000">///Performs
application-defined tasks associated with freeing, releasing, or resetting unmanaged
resources.</span>
            </pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none">
              <span style="color: #008000">///&lt;/summary&gt;</span>
            </pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
              <span style="color: #0000ff">public</span>
              <span style="color: #0000ff">void</span> Dispose()</pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none">        {</pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">            Dispose(<span style="color: #0000ff">true</span>);</pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none">            GC.SuppressFinalize(<span style="color: #0000ff">this</span>);</pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">        }</pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"> </pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
              <span style="color: #cc6633">#endregion</span>
            </pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"> </pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
              <span style="color: #cc6633">#region</span>
              <span style="color: #0000ff">private</span> API</pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"> </pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
              <span style="color: #008000">///
&lt;summary&gt;</span>
            </pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none">
              <span style="color: #008000">///
Get the next line in the file.</span>
            </pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
              <span style="color: #008000">///
dev: assume that the lock is from the outside, by the caller (this is why it's a private
method)</span>
            </pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none">
              <span style="color: #008000">///
&lt;/summary&gt;</span>
            </pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
              <span style="color: #0000ff">private</span>
              <span style="color: #0000ff">bool</span> TryGetNextLineAssumingInsideLock(<span style="color: #0000ff">out</span><span style="color: #0000ff">string</span> nextItem)</pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none">        {</pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">            nextItem = <span style="color: #0000ff">null</span>;</pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none">
              <span style="color: #0000ff">if</span> (_linesGiven
== _limit)</pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
              <span style="color: #0000ff">return</span>
              <span style="color: #0000ff">false</span>; <span style="color: #008000">//
we reached the limit, no more please.</span></pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"> </pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
              <span style="color: #0000ff">if</span> (!_enumerator.MoveNext())</pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none">
              <span style="color: #0000ff">return</span>
              <span style="color: #0000ff">false</span>; <span style="color: #008000">//
end of stream (EOF)</span></pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"> </pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none">            nextItem = _enumerator.Current;</pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">            _linesGiven++;</pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none">
              <span style="color: #0000ff">return</span>
              <span style="color: #0000ff">true</span>;</pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">        }</pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"> </pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
              <span style="color: #0000ff">private</span> IEnumerable&lt;<span style="color: #0000ff">string</span>&gt;
CreateStream()</pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none">        {</pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
              <span style="color: #0000ff">using</span> (FileStream
fs = <span style="color: #0000ff">new</span> FileStream(_path, FileMode.Open, FileAccess.Read,
FileShare.Read, 1024, FileOptions.SequentialScan))</pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none">
              <span style="color: #0000ff">using</span> (StreamReader
reader = <span style="color: #0000ff">new</span> StreamReader(fs))</pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">            {</pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none">
              <span style="color: #0000ff">string</span> line;</pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
              <span style="color: #0000ff">while</span> ((line
= reader.ReadLine()) != <span style="color: #0000ff">null</span>)</pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none">                {</pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
              <span style="color: #0000ff">if</span> (_ignoreEmptyLines
&amp;&amp; line == <span style="color: #0000ff">string</span>.Empty)</pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none">
              <span style="color: #0000ff">continue</span>; <span style="color: #008000">//
skip empty lines if needed</span></pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"> </pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none">
              <span style="color: #0000ff">yield</span>
              <span style="color: #0000ff">return</span> line;</pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">                }</pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"> </pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
              <span style="color: #0000ff">yield</span>
              <span style="color: #0000ff">break</span>;</pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none">            }</pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">        }</pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"> </pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
              <span style="color: #0000ff">protected</span>
              <span style="color: #0000ff">void</span> Dispose(<span style="color: #0000ff">bool</span> disposing)</pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none">        {</pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
              <span style="color: #0000ff">if</span> (_disposed)</pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none">
              <span style="color: #0000ff">return</span>;</pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"> </pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none">
              <span style="color: #0000ff">if</span> (disposing)</pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">            {</pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none">                _enumerator.Dispose();</pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">            }</pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"> </pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">            _disposed = <span style="color: #0000ff">true</span>;</pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none">        }</pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"> </pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none">
              <span style="color: #cc6633">#endregion</span>
            </pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">    }</pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none">}</pre>
          </div>
        </div>
        <img width="0" height="0" src="http://lnbogen.com/aggbug.ashx?id=4d6edfa8-c3a5-4aca-b34a-d597be0095a9" />
      </body>
      <title>FileStreamer</title>
      <guid isPermaLink="false">http://lnbogen.com/PermaLink,guid,4d6edfa8-c3a5-4aca-b34a-d597be0095a9.aspx</guid>
      <link>http://lnbogen.com/2008/12/30/FileStreamer.aspx</link>
      <pubDate>Tue, 30 Dec 2008 19:17:53 GMT</pubDate>
      <description>&lt;p&gt;
Requirements:
&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
Be able to read all the lines in a given file. 
&lt;li&gt;
Be able to do so even if the file is HUGE ( == don't load it all at once). 
&lt;li&gt;
Control the number of items I want to receive and whether or not the enumerator ignore
empty lines. Always nice to have. 
&lt;li&gt;
Thread-safe should be supported easily. Think about 50 threads, each reading the next
line and processing it. 
&lt;li&gt;
Nice performance is a plus.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;
&lt;br&gt;
Playing with the API with my teammate &lt;a href="http://ripper234.com/"&gt;Ron&lt;/a&gt; gave
the following (code written in notepad, stupidity won't compile):
&lt;/p&gt;
&lt;h4&gt;"Common foreach" usage:
&lt;/h4&gt;
&lt;p&gt;
foreach (string line in FileStreamer.GetLines(@"c:\temp\myfile.txt", true, 1000))
{ /* .. code */ } // read 1000 items from the file while ignoring empty lines.
&lt;/p&gt;
&lt;h4&gt;
&lt;br&gt;
Reading from multiple threads usage:
&lt;/h4&gt;
&lt;p&gt;
using (FileStreamer streamer = new FileStreamer(@"c:\temp\myfile.txt", true, -1))
// -1 means no limit, read all non-empty lines&lt;br&gt;
{&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; Thread[] threads = new Thread[10];&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; for(int i=0; i&amp;lt;threads.Length; i++)&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; threads[i] = new Thread((ThreadStart)delegate
{ 
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; string line;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (!streamer.TryGetNextLine(out
line)) // thread safe!&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
return; // end of file, we can exit&lt;br&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // do work ...&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }); 
&lt;p&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; threads[i].Start();&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; } 
&lt;p&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; // join the threads + whatever ...&lt;br&gt;
} 
&lt;p&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p&gt;
After reading a few ideas in &lt;a href="http://stackoverflow.com/questions/286533/filestream-streamreader-problem-in-c"&gt;stackoverflow&lt;/a&gt;,
I thought to share my solution:&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 
&lt;/p&gt;
&lt;div style="border-right: gray 1px solid; padding-right: 4px; border-top: gray 1px solid; padding-left: 4px; font-size: 8pt; padding-bottom: 4px; margin: 20px 0px 10px; overflow: auto; border-left: gray 1px solid; width: 97.5%; cursor: text; max-height: 200px; line-height: 12pt; padding-top: 4px; border-bottom: gray 1px solid; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4"&gt;
&lt;div style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #008000"&gt;//
written by bogen (30/12/2008)&lt;/span&gt;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&amp;nbsp;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #cc6633"&gt;#region&lt;/span&gt; &lt;span style="color: #0000ff"&gt;using&lt;/span&gt;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&amp;nbsp;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #0000ff"&gt;using&lt;/span&gt; System;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #0000ff"&gt;using&lt;/span&gt; System.Collections.Generic;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #0000ff"&gt;using&lt;/span&gt; System.IO;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&amp;nbsp;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #cc6633"&gt;#endregion&lt;/span&gt;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&amp;nbsp;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #0000ff"&gt;namespace&lt;/span&gt; Semingo.Common.Utils&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;{&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;    &lt;span style="color: #008000"&gt;///
&amp;lt;summary&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;    &lt;span style="color: #008000"&gt;///
Return a stream of lines for the specified file.&lt;/span&gt;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;    &lt;span style="color: #008000"&gt;///
This class is thread safe by design!&lt;/span&gt;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;    &lt;span style="color: #008000"&gt;///
Use the static method FileStreamer.GetLines for not thread safe usage (via foreach)&lt;/span&gt;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;    &lt;span style="color: #008000"&gt;///
&amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;    &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;class&lt;/span&gt; FileStreamer
: IDisposable&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;    {&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;        &lt;span style="color: #cc6633"&gt;#region&lt;/span&gt; fields&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&amp;nbsp;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;        &lt;span style="color: #0000ff"&gt;private&lt;/span&gt; &lt;span style="color: #0000ff"&gt;readonly&lt;/span&gt; &lt;span style="color: #0000ff"&gt;object&lt;/span&gt; _locker
= &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; &lt;span style="color: #0000ff"&gt;object&lt;/span&gt;();&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;        &lt;span style="color: #0000ff"&gt;private&lt;/span&gt; &lt;span style="color: #0000ff"&gt;readonly&lt;/span&gt; &lt;span style="color: #0000ff"&gt;string&lt;/span&gt; _path;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;        &lt;span style="color: #0000ff"&gt;private&lt;/span&gt; &lt;span style="color: #0000ff"&gt;readonly&lt;/span&gt; &lt;span style="color: #0000ff"&gt;bool&lt;/span&gt; _ignoreEmptyLines;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;        &lt;span style="color: #0000ff"&gt;private&lt;/span&gt; &lt;span style="color: #0000ff"&gt;readonly&lt;/span&gt; &lt;span style="color: #0000ff"&gt;int&lt;/span&gt; _limit;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;        &lt;span style="color: #0000ff"&gt;private&lt;/span&gt; &lt;span style="color: #0000ff"&gt;readonly&lt;/span&gt; IEnumerator&amp;lt;&lt;span style="color: #0000ff"&gt;string&lt;/span&gt;&amp;gt;
_enumerator;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;        &lt;span style="color: #0000ff"&gt;private&lt;/span&gt; &lt;span style="color: #0000ff"&gt;int&lt;/span&gt; _linesGiven;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;        &lt;span style="color: #0000ff"&gt;private&lt;/span&gt; &lt;span style="color: #0000ff"&gt;bool&lt;/span&gt; _disposed;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&amp;nbsp;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;        &lt;span style="color: #cc6633"&gt;#endregion&lt;/span&gt;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&amp;nbsp;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;        &lt;span style="color: #cc6633"&gt;#region&lt;/span&gt; ctors&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&amp;nbsp;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;        &lt;span style="color: #008000"&gt;///
&amp;lt;summary&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;        &lt;span style="color: #008000"&gt;///
Create a file streamer instance&lt;/span&gt;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;        &lt;span style="color: #008000"&gt;///
&amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;        &lt;span style="color: #008000"&gt;///
&amp;lt;param name="path"&amp;gt;File path&amp;lt;/param&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;        &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; FileStreamer(&lt;span style="color: #0000ff"&gt;string&lt;/span&gt; path)
: &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;(path, &lt;span style="color: #0000ff"&gt;false&lt;/span&gt;,
-1)&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;        {&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;        }&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&amp;nbsp;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;        &lt;span style="color: #008000"&gt;///
&amp;lt;summary&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;        &lt;span style="color: #008000"&gt;///
Create a file streamer instance&lt;/span&gt;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;        &lt;span style="color: #008000"&gt;///
&amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;        &lt;span style="color: #008000"&gt;///
&amp;lt;param name="path"&amp;gt;File path&amp;lt;/param&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;        &lt;span style="color: #008000"&gt;///
&amp;lt;param name="ignoreEmptyLines"&amp;gt;Should the streamer avoid empty lines&amp;lt;/param&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;        &lt;span style="color: #008000"&gt;///
&amp;lt;param name="limit"&amp;gt;Number of maximum lines the streamer should return. Send
-1 for no limit&amp;lt;/param&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;        &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; FileStreamer(&lt;span style="color: #0000ff"&gt;string&lt;/span&gt; path, &lt;span style="color: #0000ff"&gt;bool&lt;/span&gt; ignoreEmptyLines, &lt;span style="color: #0000ff"&gt;int&lt;/span&gt; limit)&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;        {&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;            &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (!File.Exists(path))&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;                &lt;span style="color: #0000ff"&gt;throw&lt;/span&gt; &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; ArgumentException(&lt;span style="color: #006080"&gt;"Cannot
find the file: "&lt;/span&gt; + path);&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;            &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (limit
!= -1 &amp;amp;&amp;amp; limit &amp;lt;=0 )&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;                &lt;span style="color: #0000ff"&gt;throw&lt;/span&gt; &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; ArgumentException(&lt;span style="color: #006080"&gt;"Limit
must be bigger than 0 (or -1 for no limit) but was: "&lt;/span&gt; + limit + &lt;span style="color: #006080"&gt;".
File given was: "&lt;/span&gt; + path);&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&amp;nbsp;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;            _path = path;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;            _ignoreEmptyLines = ignoreEmptyLines;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;            _limit = limit;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;            &lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;            _enumerator = CreateStream().GetEnumerator();&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;        }&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&amp;nbsp;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;        &lt;span style="color: #cc6633"&gt;#endregion&lt;/span&gt;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&amp;nbsp;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;        &lt;span style="color: #cc6633"&gt;#region&lt;/span&gt; &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; API&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&amp;nbsp;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;        &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;bool&lt;/span&gt; TryGetNextLine(&lt;span style="color: #0000ff"&gt;out&lt;/span&gt; &lt;span style="color: #0000ff"&gt;string&lt;/span&gt; nextItem)&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;        {&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;            &lt;span style="color: #0000ff"&gt;lock&lt;/span&gt; (_locker)&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;            {&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;                &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; TryGetNextLineAssumingInsideLock(&lt;span style="color: #0000ff"&gt;out&lt;/span&gt; nextItem);&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;            }&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;        }&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&amp;nbsp;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;        &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;bool&lt;/span&gt; TryGetNextLines(&lt;span style="color: #0000ff"&gt;out&lt;/span&gt; ICollection&amp;lt;&lt;span style="color: #0000ff"&gt;string&lt;/span&gt;&amp;gt;
nextItems, &lt;span style="color: #0000ff"&gt;int&lt;/span&gt; howMany)&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;        {&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;            &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (howMany
&amp;lt;= 0)&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;                &lt;span style="color: #0000ff"&gt;throw&lt;/span&gt; &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; ArgumentException(&lt;span style="color: #006080"&gt;"'howMany'
parameter must be &amp;gt; 0 but was "&lt;/span&gt; + howMany, &lt;span style="color: #006080"&gt;"howMany"&lt;/span&gt;);&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&amp;nbsp;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;            nextItems = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; List&amp;lt;&lt;span style="color: #0000ff"&gt;string&lt;/span&gt;&amp;gt;(howMany);&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;            &lt;span style="color: #0000ff"&gt;lock&lt;/span&gt; (_locker)&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;            {&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;                &lt;span style="color: #0000ff"&gt;string&lt;/span&gt; nextItem;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;                &lt;span style="color: #0000ff"&gt;for&lt;/span&gt;(&lt;span style="color: #0000ff"&gt;int&lt;/span&gt; i=0;
i&amp;lt;howMany; i++)&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;                {&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;                    &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (!TryGetNextLineAssumingInsideLock(&lt;span style="color: #0000ff"&gt;out&lt;/span&gt; nextItem))&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;                        &lt;span style="color: #0000ff"&gt;break&lt;/span&gt;; &lt;span style="color: #008000"&gt;//
no more lines (EOF)&lt;/span&gt;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;                    &lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;                    nextItems.Add(nextItem);&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;                }&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;            }&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&amp;nbsp;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;            &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; nextItems.Count
&amp;gt; 0;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;        }&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;       &lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;        &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;static&lt;/span&gt; IEnumerable&amp;lt;&lt;span style="color: #0000ff"&gt;string&lt;/span&gt;&amp;gt;
GetLines(&lt;span style="color: #0000ff"&gt;string&lt;/span&gt; path)&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;        {&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;            &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; GetLines(path, &lt;span style="color: #0000ff"&gt;false&lt;/span&gt;,
-1);&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;        }&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&amp;nbsp;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;        &lt;span style="color: #008000"&gt;///
&amp;lt;summary&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;        &lt;span style="color: #008000"&gt;/// &lt;/span&gt;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;        &lt;span style="color: #008000"&gt;///
&amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;        &lt;span style="color: #008000"&gt;///
&amp;lt;param name="path"&amp;gt;&amp;lt;/param&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;        &lt;span style="color: #008000"&gt;///
&amp;lt;param name="ignoreEmptyLines"&amp;gt;&amp;lt;/param&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;        &lt;span style="color: #008000"&gt;///
&amp;lt;param name="limit"&amp;gt;send -1 for no limit&amp;lt;/param&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;        &lt;span style="color: #008000"&gt;///
&amp;lt;returns&amp;gt;&amp;lt;/returns&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;        &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;static&lt;/span&gt; IEnumerable&amp;lt;&lt;span style="color: #0000ff"&gt;string&lt;/span&gt;&amp;gt;
GetLines(&lt;span style="color: #0000ff"&gt;string&lt;/span&gt; path, &lt;span style="color: #0000ff"&gt;bool&lt;/span&gt; ignoreEmptyLines, &lt;span style="color: #0000ff"&gt;int&lt;/span&gt; limit)&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;        {&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;            &lt;span style="color: #0000ff"&gt;using&lt;/span&gt; (FileStreamer
streamer = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; FileStreamer(path, ignoreEmptyLines,
limit))&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;            {&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;                &lt;span style="color: #0000ff"&gt;string&lt;/span&gt; nextItem;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;                &lt;span style="color: #0000ff"&gt;while&lt;/span&gt; (streamer.TryGetNextLine(&lt;span style="color: #0000ff"&gt;out&lt;/span&gt; nextItem))&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;                    &lt;span style="color: #0000ff"&gt;yield&lt;/span&gt; &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; nextItem;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&amp;nbsp;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;                &lt;span style="color: #0000ff"&gt;yield&lt;/span&gt; &lt;span style="color: #0000ff"&gt;break&lt;/span&gt;; &lt;span style="color: #008000"&gt;//
EOF&lt;/span&gt;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;            }&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;        }&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&amp;nbsp;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;        &lt;span style="color: #008000"&gt;///&amp;lt;summary&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;        &lt;span style="color: #008000"&gt;///Performs
application-defined tasks associated with freeing, releasing, or resetting unmanaged
resources.&lt;/span&gt;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;        &lt;span style="color: #008000"&gt;///&amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;        &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; Dispose()&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;        {&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;            Dispose(&lt;span style="color: #0000ff"&gt;true&lt;/span&gt;);&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;            GC.SuppressFinalize(&lt;span style="color: #0000ff"&gt;this&lt;/span&gt;);&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;        }&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&amp;nbsp;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;        &lt;span style="color: #cc6633"&gt;#endregion&lt;/span&gt;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&amp;nbsp;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;        &lt;span style="color: #cc6633"&gt;#region&lt;/span&gt; &lt;span style="color: #0000ff"&gt;private&lt;/span&gt; API&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&amp;nbsp;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;        &lt;span style="color: #008000"&gt;///
&amp;lt;summary&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;        &lt;span style="color: #008000"&gt;///
Get the next line in the file.&lt;/span&gt;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;        &lt;span style="color: #008000"&gt;///
dev: assume that the lock is from the outside, by the caller (this is why it's a private
method)&lt;/span&gt;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;        &lt;span style="color: #008000"&gt;///
&amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;        &lt;span style="color: #0000ff"&gt;private&lt;/span&gt; &lt;span style="color: #0000ff"&gt;bool&lt;/span&gt; TryGetNextLineAssumingInsideLock(&lt;span style="color: #0000ff"&gt;out&lt;/span&gt; &lt;span style="color: #0000ff"&gt;string&lt;/span&gt; nextItem)&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;        {&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;            nextItem = &lt;span style="color: #0000ff"&gt;null&lt;/span&gt;;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;            &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (_linesGiven
== _limit)&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;                &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; &lt;span style="color: #0000ff"&gt;false&lt;/span&gt;; &lt;span style="color: #008000"&gt;//
we reached the limit, no more please.&lt;/span&gt;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&amp;nbsp;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;            &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (!_enumerator.MoveNext())&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;                &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; &lt;span style="color: #0000ff"&gt;false&lt;/span&gt;; &lt;span style="color: #008000"&gt;//
end of stream (EOF)&lt;/span&gt;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&amp;nbsp;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;            nextItem = _enumerator.Current;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;            _linesGiven++;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;            &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; &lt;span style="color: #0000ff"&gt;true&lt;/span&gt;;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;        }&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&amp;nbsp;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;        &lt;span style="color: #0000ff"&gt;private&lt;/span&gt; IEnumerable&amp;lt;&lt;span style="color: #0000ff"&gt;string&lt;/span&gt;&amp;gt;
CreateStream()&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;        {&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;            &lt;span style="color: #0000ff"&gt;using&lt;/span&gt; (FileStream
fs = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; FileStream(_path, FileMode.Open, FileAccess.Read,
FileShare.Read, 1024, FileOptions.SequentialScan))&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;            &lt;span style="color: #0000ff"&gt;using&lt;/span&gt; (StreamReader
reader = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; StreamReader(fs))&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;            {&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;                &lt;span style="color: #0000ff"&gt;string&lt;/span&gt; line;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;                &lt;span style="color: #0000ff"&gt;while&lt;/span&gt; ((line
= reader.ReadLine()) != &lt;span style="color: #0000ff"&gt;null&lt;/span&gt;)&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;                {&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;                    &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (_ignoreEmptyLines
&amp;amp;&amp;amp; line == &lt;span style="color: #0000ff"&gt;string&lt;/span&gt;.Empty)&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;                        &lt;span style="color: #0000ff"&gt;continue&lt;/span&gt;; &lt;span style="color: #008000"&gt;//
skip empty lines if needed&lt;/span&gt;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&amp;nbsp;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;                    &lt;span style="color: #0000ff"&gt;yield&lt;/span&gt; &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; line;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;                }&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&amp;nbsp;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;                &lt;span style="color: #0000ff"&gt;yield&lt;/span&gt; &lt;span style="color: #0000ff"&gt;break&lt;/span&gt;;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;            }&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;        }&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&amp;nbsp;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;        &lt;span style="color: #0000ff"&gt;protected&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; Dispose(&lt;span style="color: #0000ff"&gt;bool&lt;/span&gt; disposing)&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;        {&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;            &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (_disposed)&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;                &lt;span style="color: #0000ff"&gt;return&lt;/span&gt;;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&amp;nbsp;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;            &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (disposing)&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;            {&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;                _enumerator.Dispose();&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;            }&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&amp;nbsp;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;            _disposed = &lt;span style="color: #0000ff"&gt;true&lt;/span&gt;;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;        }&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&amp;nbsp;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;        &lt;span style="color: #cc6633"&gt;#endregion&lt;/span&gt;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;    }&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;}&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;img width="0" height="0" src="http://lnbogen.com/aggbug.ashx?id=4d6edfa8-c3a5-4aca-b34a-d597be0095a9" /&gt;</description>
      <comments>http://lnbogen.com/CommentView,guid,4d6edfa8-c3a5-4aca-b34a-d597be0095a9.aspx</comments>
    </item>
    <item>
      <trackback:ping>http://lnbogen.com/Trackback.aspx?guid=36259054-72d3-4f37-8a93-a1e55f3e872e</trackback:ping>
      <pingback:server>http://lnbogen.com/pingback.aspx</pingback:server>
      <pingback:target>http://lnbogen.com/PermaLink,guid,36259054-72d3-4f37-8a93-a1e55f3e872e.aspx</pingback:target>
      <dc:creator>Oren Ellenbogen</dc:creator>
      <wfw:comment>http://lnbogen.com/CommentView,guid,36259054-72d3-4f37-8a93-a1e55f3e872e.aspx</wfw:comment>
      <wfw:commentRss>http://lnbogen.com/SyndicationService.asmx/GetEntryCommentsRss?guid=36259054-72d3-4f37-8a93-a1e55f3e872e</wfw:commentRss>
      <slash:comments>1</slash:comments>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
"Why do you love working as X so much? so much that you're willing to spend that many
hours of your life at?"
</p>
        <p>
Pause for a second. Try to close your eyes and think what will be your answer for
this question?
</p>
        <p>
          <br />
For me, the answer is obvious: It's the people and challenges that make my brain tick
and my motivation SKY high. It's the feeling that <strong>I</strong> can <em>really</em> make
things better by investing everything I got into it that makes me proud of my work.
I get huge satisfaction installing TFS 2008, trying to make our Integration Tests
work X6 faster, practicing some Agile principles I've read about or take any other
"dirty yet important work" no one would like to touch. I'm not scared of  hard
work and if I can feel, down there in my stomach, that it would make my teammates
more productive - I'll do anything I can to make it happen. Oh, and I'm trying to
build one of the most complex <a href="http://www.delver.com/">search engine</a> the
world has the offer with a bunch of <a href="http://ripper234.com/">b</a>-<a href="http://pashabitz.com/">r</a>-<a href="http://blog.karmona.com/">i</a>-<a href="http://www.tomergabel.com/">l</a>-<a href="http://blog.shlomoid.com/">l</a>-<a href="http://www.kenegozi.com/blog/">i</a>-<a href="http://omriqa.blogspot.com/">a</a>-<a href="http://blog.agmon.com/">n</a>-<a href="http://blog.delver.com/">t</a> guys!
Can you blame me for working so hard, enjoying <em>every</em> minute of it?
</p>
        <p>
Sure, getting a few bucks more would be great, but that will <em>not</em> make me <strong>proud</strong> of
what I'm doing. One of the main things I've learned in my 8 years of developing software,
is that highly motivated teams will always make the best products. Leave aside for
a moment the productivity boost these teams enjoy and imagine their daily work, their
lunches together, their working environment, their joy of talking with one another
about day to day stuff. Imagine how they dream about their goals together, discussing
ways to making it better and more enjoyable. It's the buzz these companies have that
drove the best guys to them, so "effortlessly". The commitment to one another will
make sure you'll build quality systems, that you'll try your best to deliver on time,
to make it better, smarter, BIGGER, <em>every</em><em>single day</em>. It will allow
you to grow like you could never anticipated. Trying to grow this culture in your
team is one of the hardest things in the world, way harder than <em>any</em> logical
puzzle thrown at you. Believe me.
</p>
        <p>
          <strong>It's just so damn hard to get it right.</strong>
        </p>
        <strong>
          <p>
            <br />
"
</p>
        </strong>There are many men who feel a kind of twister pride in cynicism<strong>"</strong> (Theodore
Roosevelt, <a href="http://www.theodore-roosevelt.com/trsorbonnespeech.html">The Man
In The Arena</a> speech).<br />
Over cynicism means death for any joint effort. No matter how strong your team is,
negativity and cynicism will break your team spirit. It always does. 
<br />
Stop being so negative, so cynical about your actions and your dreams. You can do
great things by answer the question above and remember that it's all about the people
around you. It's all about you! you can actually make everyone around you better by
taking action. Stop listening to people who thinks they know best and mocking you
with "you're only a tiny nail in a giant machine". Don't be afraid of constantly trying
to make a difference, even if you'll lose here and there. Read books, talk about them
and your ideas, share and try, try, try, and try again! 
<p>
This attitude will probably make you a winner, someone that others will enjoy working
with, being with, taking inspiration from. 
<br />
I know that these guys are the one <strong>I</strong> love working with or going to
a bar close by, drinking some beer and talking about how to change the world.<br /><br />
Best people simply do for each other.
</p><img width="0" height="0" src="http://lnbogen.com/aggbug.ashx?id=36259054-72d3-4f37-8a93-a1e55f3e872e" /></body>
      <title>Best teams work for each other</title>
      <guid isPermaLink="false">http://lnbogen.com/PermaLink,guid,36259054-72d3-4f37-8a93-a1e55f3e872e.aspx</guid>
      <link>http://lnbogen.com/2008/11/07/BestTeamsWorkForEachOther.aspx</link>
      <pubDate>Fri, 07 Nov 2008 15:40:02 GMT</pubDate>
      <description>&lt;p&gt;
"Why do you love working as X so much? so much that you're willing to spend that many
hours of your life at?"
&lt;/p&gt;
&lt;p&gt;
Pause for a second. Try to close your eyes and think what will be your answer for
this question?
&lt;/p&gt;
&lt;p&gt;
&lt;br&gt;
For me, the answer is obvious: It's the people and challenges that make my brain tick
and my motivation SKY high. It's the feeling that &lt;strong&gt;I&lt;/strong&gt; can &lt;em&gt;really&lt;/em&gt; make
things better by investing everything I got into it that makes me proud of my work.
I get huge satisfaction installing TFS 2008, trying to make our Integration Tests
work X6 faster, practicing some Agile principles I've read about or take any other
"dirty yet important work" no one would like to touch. I'm not scared of&amp;nbsp; hard
work and if I can feel, down there in my stomach, that it would make my teammates
more productive - I'll do anything I can to make it happen. Oh, and I'm trying to
build one of the most complex &lt;a href="http://www.delver.com/"&gt;search engine&lt;/a&gt; the
world has the offer with a bunch of &lt;a href="http://ripper234.com/"&gt;b&lt;/a&gt;-&lt;a href="http://pashabitz.com/"&gt;r&lt;/a&gt;-&lt;a href="http://blog.karmona.com/"&gt;i&lt;/a&gt;-&lt;a href="http://www.tomergabel.com/"&gt;l&lt;/a&gt;-&lt;a href="http://blog.shlomoid.com/"&gt;l&lt;/a&gt;-&lt;a href="http://www.kenegozi.com/blog/"&gt;i&lt;/a&gt;-&lt;a href="http://omriqa.blogspot.com/"&gt;a&lt;/a&gt;-&lt;a href="http://blog.agmon.com/"&gt;n&lt;/a&gt;-&lt;a href="http://blog.delver.com/"&gt;t&lt;/a&gt; guys!
Can you blame me for working so hard, enjoying &lt;em&gt;every&lt;/em&gt; minute of it?
&lt;/p&gt;
&lt;p&gt;
Sure, getting a few bucks more would be great, but that will &lt;em&gt;not&lt;/em&gt; make me &lt;strong&gt;proud&lt;/strong&gt; of
what I'm doing. One of the main things I've learned in my 8 years of developing software,
is that highly motivated teams will always make the best products. Leave aside for
a moment the productivity boost these teams enjoy and imagine their daily work, their
lunches together, their working environment, their joy of talking with one another
about day to day stuff. Imagine how they dream about their goals together, discussing
ways to making it better and more enjoyable. It's the buzz these companies have that
drove the best guys to them, so "effortlessly". The commitment to one another will
make sure you'll build quality systems, that you'll try your best to deliver on time,
to make it better, smarter, BIGGER, &lt;em&gt;every&lt;/em&gt; &lt;em&gt;single day&lt;/em&gt;. It will allow
you to grow like you could never anticipated. Trying to grow this culture in your
team is one of the hardest things in the world, way harder than &lt;em&gt;any&lt;/em&gt; logical
puzzle thrown at you. Believe me.
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;It's just so damn hard to get it right.&lt;/strong&gt;
&lt;/p&gt;
&lt;strong&gt; 
&lt;p&gt;
&lt;br&gt;
"
&lt;/strong&gt;There are many men who feel a kind of twister pride in cynicism&lt;strong&gt;"&lt;/strong&gt; (Theodore
Roosevelt, &lt;a href="http://www.theodore-roosevelt.com/trsorbonnespeech.html"&gt;The Man
In The Arena&lt;/a&gt; speech).&lt;br&gt;
Over cynicism means death for any joint effort. No matter how strong your team is,
negativity and cynicism will break your team spirit. It always does. 
&lt;br&gt;
Stop being so negative, so cynical about your actions and your dreams. You can do
great things by answer the question above and remember that it's all about the people
around you. It's all about you! you can actually make everyone around you better by
taking action. Stop listening to people who thinks they know best and mocking you
with "you're only a tiny nail in a giant machine". Don't be afraid of constantly trying
to make a difference, even if you'll lose here and there. Read books, talk about them
and your ideas, share and try, try, try, and try again! &gt;
&lt;p&gt;
This attitude will probably make you a winner, someone that others will enjoy working
with, being with, taking inspiration from. 
&lt;br&gt;
I know that these guys are the one &lt;strong&gt;I&lt;/strong&gt; love working with or going to
a bar close by, drinking some beer and talking about how to change the world.&lt;br&gt;
&lt;br&gt;
Best people simply do for each other.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://lnbogen.com/aggbug.ashx?id=36259054-72d3-4f37-8a93-a1e55f3e872e" /&gt;</description>
      <comments>http://lnbogen.com/CommentView,guid,36259054-72d3-4f37-8a93-a1e55f3e872e.aspx</comments>
      <category>Life</category>
      <category>Management</category>
    </item>
    <item>
      <trackback:ping>http://lnbogen.com/Trackback.aspx?guid=6ebfb784-0192-44ed-a582-a0aed3e94ec7</trackback:ping>
      <pingback:server>http://lnbogen.com/pingback.aspx</pingback:server>
      <pingback:target>http://lnbogen.com/PermaLink,guid,6ebfb784-0192-44ed-a582-a0aed3e94ec7.aspx</pingback:target>
      <dc:creator>Oren Ellenbogen</dc:creator>
      <wfw:comment>http://lnbogen.com/CommentView,guid,6ebfb784-0192-44ed-a582-a0aed3e94ec7.aspx</wfw:comment>
      <wfw:commentRss>http://lnbogen.com/SyndicationService.asmx/GetEntryCommentsRss?guid=6ebfb784-0192-44ed-a582-a0aed3e94ec7</wfw:commentRss>
      <slash:comments>1</slash:comments>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
We're doing a lot of thinking these days about which features will give us the best
ROI, trying to prioritize existing features and asking ourselves "did we miss something?
is there a <em>new</em> feature out there we left behind?". It's not easy to think
about great one-of-a-kind ideas. It is easy though to make it almost impossible. 
</p>
        <p>
Why? it's all because the <a href="http://www.journalofvision.org/4/8/522/">"parallel"
right hemisphere of our brain</a>, imagine the following brain storming conversation: 
</p>
        <p>
me(<strong>L</strong>eft brain): Alright I've got one! The user will enter the screen,
do X and Y (we'll do some Z behind the scene) to receive ... 
<br />
   me(<strong>R</strong>ight brain kicks in): but, doing Z will take me
two weeks to develop..<br />
   me(R): gosh, we'll need to build a dictionary and hold it in memory if
we want it to scale..<br />
   me(R): reminder, use ReaderWriteLockSlim this time. It's much faster
than ReaderWriterLock!<br />
   me(R): I guess that this feature is not as important as feature F1, maybe
I'm spending my time thinking about this feature??!<br />
   me(R): I'm so hungry!<br />
   me(R): Oh, we can use [some service name] to do Z. Cool, so now this
feature is feasible.<br />
   me(R): crap, [some service name] cost money, I think.<br /><br />
[To the surrounding, it looks like I'm saying one fluent sentence of course. During
that time they have their right brain working on "why not" / "how" / "when"]<br />
 <br />
   joe(R): gosh, is he for real? this is the lamest idea I've heard!<br />
   jack(R): hmm, maybe he have a point there. This feature reminds me something
I've always wanted to do... what was it now??...<br />
   jack(R): naa.. this guy is crazy. for sure.<br />
   joe(R): oh wait! we can use something I wrote to implement this feature!
might be cool to use this code finally. It is laying there for ages.<br />
   sarah(R): wonderful idea! I wonder if I'll be assigned to work on it?<br />
   jack(R): I'm listening to his bubbling for 20 minutes now. self reminder:
talk about a bonus with the CEO.<br />
   sarah(R): I need coffee! God, if you'll end this meeting now I promise
the donate 10$ for charity! coffee... please...
</p>
        <p>
me(L): .. a brilliant search result !!
</p>
        <p>
          <br />
Any wonder that most brain storming meetings are futile?
</p>
        <p>
          <br />
Brain storming is a process that should be mastered and I suggest that you'll jump
to the nearest browser to find books at the topic, it's a skill worth investing time
at.<br />
Before you do so, here are some rules <em>I use</em> to silent my right brain while
doing Left Brain Storming:
</p>
        <ol>
          <li>
Never ever prioritize your ideas <em>during</em> brain storming. I can't stress enough
how important is this rule. Don't worry about it <em>now</em>, you'll have time later.  
</li>
          <li>
Listen to others. 
</li>
          <li>
Be patient = don't judge quality of ideas. 
</li>
          <li>
Write everything down. I really mean everything! There are no "stupid ideas" now. 
</li>
          <li>
            <em>You</em> are <em>not</em> going to execute these ideas. At least that is what
you should tell your right brain during that time. 
</li>
          <li>
Understand the meaning behind the feature, imagine how it will work, not how it will
be executed! 
</li>
          <li>
Don't invest more than 2 hours in a single brain storming meeting. If you feel you've
missed some ideas, rest a few hours (or even better - a few days) and then give it
another shoot. "Burned out quickly, left brain does. Burned out leads to impatience.
Impatience kicking the right brain in action. Right brain means trouble for your brain
storming meeting" -- so does <a href="http://en.wikipedia.org/wiki/Yoda">Master Yoda</a> say
(well, sort of) 
</li>
          <li>
80/20: after you're done throwing out ideas (or the 2h gong), go over the features
you've raised and mark features you think are interesting and feasible with 80 and
features that are not with 20. This should take no longer than 2 minutes, so please
use only 80 and 20 as numbers. 
</li>
          <li>
Set a separate meeting to prioritize features with the existing backlog you've got.
Important: don't do it at the same day, you'll probably want to sleep things over.</li>
        </ol>
        <p>
          <br />
Happy hunting!
</p>
        <img width="0" height="0" src="http://lnbogen.com/aggbug.ashx?id=6ebfb784-0192-44ed-a582-a0aed3e94ec7" />
      </body>
      <title>Left Brain Storming</title>
      <guid isPermaLink="false">http://lnbogen.com/PermaLink,guid,6ebfb784-0192-44ed-a582-a0aed3e94ec7.aspx</guid>
      <link>http://lnbogen.com/2008/10/31/LeftBrainStorming.aspx</link>
      <pubDate>Fri, 31 Oct 2008 13:14:30 GMT</pubDate>
      <description>&lt;p&gt;
We're doing a lot of thinking these days about which features will give us the best
ROI, trying to prioritize existing features and asking ourselves "did we miss something?
is there a &lt;em&gt;new&lt;/em&gt; feature out there we left behind?". It's not easy to think
about great one-of-a-kind ideas. It is easy though to make it almost impossible. 
&lt;/p&gt;
&lt;p&gt;
Why? it's all because the &lt;a href="http://www.journalofvision.org/4/8/522/"&gt;"parallel"
right hemisphere of our brain&lt;/a&gt;, imagine the following brain storming conversation: 
&lt;/p&gt;
&lt;p&gt;
me(&lt;strong&gt;L&lt;/strong&gt;eft brain): Alright I've got one! The user will enter the screen,
do X and Y (we'll do some Z behind the scene) to receive ... 
&lt;br&gt;
&amp;nbsp;&amp;nbsp; me(&lt;strong&gt;R&lt;/strong&gt;ight brain kicks in): but, doing Z will take me
two weeks to develop..&lt;br&gt;
&amp;nbsp;&amp;nbsp; me(R): gosh, we'll need to build a dictionary and hold it in memory if
we want it to scale..&lt;br&gt;
&amp;nbsp;&amp;nbsp; me(R): reminder, use ReaderWriteLockSlim this time. It's much faster
than ReaderWriterLock!&lt;br&gt;
&amp;nbsp;&amp;nbsp; me(R): I guess that this feature is not as important as feature F1, maybe
I'm spending my time thinking about this feature??!&lt;br&gt;
&amp;nbsp;&amp;nbsp; me(R): I'm so hungry!&lt;br&gt;
&amp;nbsp;&amp;nbsp; me(R): Oh, we can use [some service name] to do Z. Cool, so now this
feature is feasible.&lt;br&gt;
&amp;nbsp;&amp;nbsp; me(R): crap, [some service name] cost money, I think.&lt;br&gt;
&lt;br&gt;
[To the surrounding, it looks like I'm saying one fluent sentence of course. During
that time they have their right brain working on "why not" / "how" / "when"]&lt;br&gt;
&amp;nbsp;&lt;br&gt;
&amp;nbsp;&amp;nbsp; joe(R): gosh, is he for real? this is the lamest idea I've heard!&lt;br&gt;
&amp;nbsp;&amp;nbsp; jack(R): hmm, maybe he have a point there. This feature reminds me something
I've always wanted to do... what was it now??...&lt;br&gt;
&amp;nbsp;&amp;nbsp; jack(R): naa.. this guy is crazy. for sure.&lt;br&gt;
&amp;nbsp;&amp;nbsp; joe(R): oh wait! we can use something I wrote to implement this feature!
might be cool to use this code finally. It is laying there for ages.&lt;br&gt;
&amp;nbsp;&amp;nbsp; sarah(R): wonderful idea! I wonder if I'll be assigned to work on it?&lt;br&gt;
&amp;nbsp;&amp;nbsp; jack(R): I'm listening to his bubbling for 20 minutes now. self reminder:
talk about a bonus with the CEO.&lt;br&gt;
&amp;nbsp;&amp;nbsp; sarah(R): I need coffee! God, if you'll end this meeting now I promise
the donate 10$ for charity! coffee... please...
&lt;/p&gt;
&lt;p&gt;
me(L): .. a brilliant search result !!
&lt;/p&gt;
&lt;p&gt;
&lt;br&gt;
Any wonder that most brain storming meetings are futile?
&lt;/p&gt;
&lt;p&gt;
&lt;br&gt;
Brain storming is a process that should be mastered and I suggest that you'll jump
to the nearest browser to find books at the topic, it's a skill worth investing time
at.&lt;br&gt;
Before you do so, here are some rules &lt;em&gt;I use&lt;/em&gt; to silent my right brain while
doing Left Brain Storming:
&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
Never ever prioritize your ideas &lt;em&gt;during&lt;/em&gt; brain storming. I can't stress enough
how important is this rule. Don't worry about it &lt;em&gt;now&lt;/em&gt;, you'll have time later.&amp;nbsp; 
&lt;li&gt;
Listen to others. 
&lt;li&gt;
Be patient = don't judge quality of ideas. 
&lt;li&gt;
Write everything down. I really mean everything! There are no "stupid ideas" now. 
&lt;li&gt;
&lt;em&gt;You&lt;/em&gt; are &lt;em&gt;not&lt;/em&gt; going to execute these ideas. At least that is what
you should tell your right brain during that time. 
&lt;li&gt;
Understand the meaning behind the feature, imagine how it will work, not how it will
be executed! 
&lt;li&gt;
Don't invest more than 2 hours in a single brain storming meeting. If you feel you've
missed some ideas, rest a few hours (or even better - a few days) and then give it
another shoot. "Burned out quickly, left brain does. Burned out leads to impatience.
Impatience kicking the right brain in action. Right brain means trouble for your brain
storming meeting" -- so does &lt;a href="http://en.wikipedia.org/wiki/Yoda"&gt;Master Yoda&lt;/a&gt; say
(well, sort of) 
&lt;li&gt;
80/20: after you're done throwing out ideas (or the 2h gong), go over the features
you've raised and mark features you think are interesting and feasible with 80 and
features that are not with 20. This should take no longer than 2 minutes, so please
use only 80 and 20 as numbers. 
&lt;li&gt;
Set a separate meeting to prioritize features with the existing backlog you've got.
Important: don't do it at the same day, you'll probably want to sleep things over.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;
&lt;br&gt;
Happy hunting!
&lt;/p&gt;
&lt;img width="0" height="0" src="http://lnbogen.com/aggbug.ashx?id=6ebfb784-0192-44ed-a582-a0aed3e94ec7" /&gt;</description>
      <comments>http://lnbogen.com/CommentView,guid,6ebfb784-0192-44ed-a582-a0aed3e94ec7.aspx</comments>
      <category>Agile</category>
      <category>Management</category>
    </item>
    <item>
      <trackback:ping>http://lnbogen.com/Trackback.aspx?guid=5dd36c56-0901-490b-a137-268871050d92</trackback:ping>
      <pingback:server>http://lnbogen.com/pingback.aspx</pingback:server>
      <pingback:target>http://lnbogen.com/PermaLink,guid,5dd36c56-0901-490b-a137-268871050d92.aspx</pingback:target>
      <dc:creator>Oren Ellenbogen</dc:creator>
      <wfw:comment>http://lnbogen.com/CommentView,guid,5dd36c56-0901-490b-a137-268871050d92.aspx</wfw:comment>
      <wfw:commentRss>http://lnbogen.com/SyndicationService.asmx/GetEntryCommentsRss?guid=5dd36c56-0901-490b-a137-268871050d92</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
[ <a href="http://www.lnbogen.com/Part1SpawnEnumeratorDealingWithBillionsOfIndependentItems.aspx">Part
1</a>, <a href="http://www.lnbogen.com/Part2SpawnEnumeratorDealingWithBillionsOfIndependentItems.aspx">Part
2</a>, this is <a href="http://www.lnbogen.com/Part3SpawnEnumeratorDealingWithBillionsOfIndependentItems.aspx">Part
3</a> ]<br /><br />
In <a href="http://www.lnbogen.com/Part1SpawnEnumeratorDealingWithBillionsOfIndependentItems.aspx">part
1</a> I've talked about the general notion behind SpawnEnumerator. In <a href="http://www.lnbogen.com/Part2SpawnEnumeratorDealingWithBillionsOfIndependentItems.aspx">part
2</a> I've implemented it and talked a bit about CCR and how it works under the hood.<br />
In the third and last part I'll try to show how we can actually execute billions of
tasks very easily.<br /><br /><strong>Iterating over billions of tasks:</strong></p>
        <p>
In my <a href="http://www.lnbogen.com/TheBeautyOfYieldStatement.aspx">previous post</a> I've
tried to show one of the greatest yet unused features in C# 2.0 - the yield statement.
I've closed the post with:<br />
"Prefer using the yield statement as long as calculating values doesn't require <strong>holding</strong> an
expensive resource like a DB connection, or a FileHandler for <strong>long period
of time</strong>."
</p>
        <p>
Now, let's assume that we have 100,000,000 Tasks to pull from a repository (DB, files,
doesn't really matter) and execute them all via SpawnEnumerator. 
<br />
Should we define a list of Task, fill it with 100,000,000 items and then iterate over
it? of course not! we can't even if we want to.<br />
Assuming that reading 1000 (for example) Tasks is <strong>much faster</strong> than
executing them (it usually is), and it's safe to hold them in memory, we can "bulk
read &amp; yield" the entire thing:
</p>
        <blockquote>
          <p>
public delegate T Func&lt;T&gt;();
</p>
        </blockquote>
        <blockquote>
          <p>
public static class Yield<br />
{<br />
    public static IEnumerable&lt;T&gt; Bulked&lt;T&gt;(Func&lt;IEnumerable&lt;T&gt;&gt;
bulkYielder)<br />
    {<br />
        while (true)<br />
        {<br />
            IEnumerable&lt;T&gt;
yielder = bulkYielder();<br />
            if (yielder ==
null)<br />
               
throw new ArgumentException("bulkYielder cannot return a null enumerable", "bulkYielder"); 
</p>
        </blockquote>
        <blockquote>
          <p>
            int itemsGiven
= 0;<br />
            foreach (T t in
yielder)<br />
            {<br />
               
itemsGiven++;<br />
               
yield return t;<br />
            } 
</p>
        </blockquote>
        <blockquote>
          <p>
            if (itemsGiven
== 0)<br />
               
break;<br />
        }<br />
    }<br />
}
</p>
        </blockquote>
        <p>
This can be used to return a stream of "tasks bulk" :
</p>
        <blockquote>
          <p>
Yield.Bulked&lt;Task&gt;(delegate { return tasksRepository.Dequeue(1000); }) // return
the <strong>next</strong> 1000 from the 100,000,000 items queue until no more tasks
exists in the repository.
</p>
        </blockquote>
        <blockquote>
          <p>
            <strong>Important note</strong>: 
<br />
In this scenario, we should return 1000 items from Dequeue method <strong>without</strong> using
yield to avoid holding expensive resources for long period of time (as discussed).<br />
Once we have those 1000 items, we can yield each one of them to the caller (very cheap,
no resources are used).
</p>
        </blockquote>
        <p>
Finally, we can execute billions of tasks in parallel via SpawnEnumerator:
</p>
        <blockquote>
          <p>
IEnumerator&lt;Task&gt; tasksEnumerator = Yield.Bulked&lt;Task&gt;(delegate { return
tasksRepository.Dequeue(1000); });<br />
Action&lt;Task&gt; taskHandler = delegate(Task t) { /* execute single task */ }; 
</p>
        </blockquote>
        <blockquote>
          <p>
// execute the tasks in parallel, using 50 threads and holding ~1000 items in memory.<br />
_tasksExecutor = SpawnEnumerator&lt;Task&gt;.Start(50, "mypool", 1000, tasksEnumerator,
taskHandler); 
</p>
          <p>
// note:don't forget to dispose _tasksExecutor when killing/stopping app!
</p>
        </blockquote>
        <p>
          <br />
Using Yield.Bulked guarantees that we won't hold expensive resources for too long
while allowing us to generate a "stream" of Tasks to run in parallel.<br />
The code is easy to read and follow (I hope) and we gain a simple method for executing
billions of tasks very effectively (CPU &amp; memory wise).
</p>
        <img width="0" height="0" src="http://lnbogen.com/aggbug.ashx?id=5dd36c56-0901-490b-a137-268871050d92" />
      </body>
      <title>Part3: SpawnEnumerator, dealing with billions of independent items</title>
      <guid isPermaLink="false">http://lnbogen.com/PermaLink,guid,5dd36c56-0901-490b-a137-268871050d92.aspx</guid>
      <link>http://lnbogen.com/2008/10/18/Part3SpawnEnumeratorDealingWithBillionsOfIndependentItems.aspx</link>
      <pubDate>Sat, 18 Oct 2008 23:39:07 GMT</pubDate>
      <description>&lt;p&gt;
[ &lt;a href="http://www.lnbogen.com/Part1SpawnEnumeratorDealingWithBillionsOfIndependentItems.aspx"&gt;Part
1&lt;/a&gt;, &lt;a href="http://www.lnbogen.com/Part2SpawnEnumeratorDealingWithBillionsOfIndependentItems.aspx"&gt;Part
2&lt;/a&gt;, this is &lt;a href="http://www.lnbogen.com/Part3SpawnEnumeratorDealingWithBillionsOfIndependentItems.aspx"&gt;Part
3&lt;/a&gt; ]&lt;br&gt;
&lt;br&gt;
In &lt;a href="http://www.lnbogen.com/Part1SpawnEnumeratorDealingWithBillionsOfIndependentItems.aspx"&gt;part
1&lt;/a&gt; I've talked about the general notion behind SpawnEnumerator. In &lt;a href="http://www.lnbogen.com/Part2SpawnEnumeratorDealingWithBillionsOfIndependentItems.aspx"&gt;part
2&lt;/a&gt; I've implemented it and talked a bit about CCR and how it works under the hood.&lt;br&gt;
In the third and last part I'll try to show how we can actually execute billions of
tasks very easily.&lt;br&gt;
&lt;br&gt;
&lt;strong&gt;Iterating over billions of tasks:&lt;/strong&gt;
&lt;/p&gt;
&lt;p&gt;
In my &lt;a href="http://www.lnbogen.com/TheBeautyOfYieldStatement.aspx"&gt;previous post&lt;/a&gt; I've
tried to show one of the greatest yet unused features in C# 2.0 - the yield statement.
I've closed the post with:&lt;br&gt;
"Prefer using the yield statement as long as calculating values doesn't require &lt;strong&gt;holding&lt;/strong&gt; an
expensive resource like a DB connection, or a FileHandler for &lt;strong&gt;long period
of time&lt;/strong&gt;."
&lt;/p&gt;
&lt;p&gt;
Now, let's assume that we have 100,000,000 Tasks to pull from a repository (DB, files,
doesn't really matter) and execute them all via SpawnEnumerator. 
&lt;br&gt;
Should we define a list of Task, fill it with 100,000,000 items and then iterate over
it? of course not! we can't even if we want to.&lt;br&gt;
Assuming that reading 1000 (for example) Tasks is &lt;strong&gt;much faster&lt;/strong&gt; than
executing them (it usually is), and it's safe to hold them in memory, we can "bulk
read &amp;amp; yield" the entire thing:
&lt;/p&gt;
&lt;blockquote&gt; 
&lt;p&gt;
public delegate T Func&amp;lt;T&amp;gt;();
&lt;/p&gt;
&lt;/blockquote&gt; &lt;blockquote&gt; 
&lt;p&gt;
public static class Yield&lt;br&gt;
{&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; public static IEnumerable&amp;lt;T&amp;gt; Bulked&amp;lt;T&amp;gt;(Func&amp;lt;IEnumerable&amp;lt;T&amp;gt;&amp;gt;
bulkYielder)&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; while (true)&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; IEnumerable&amp;lt;T&amp;gt;
yielder = bulkYielder();&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (yielder ==
null)&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
throw new ArgumentException("bulkYielder cannot return a null enumerable", "bulkYielder"); 
&lt;/p&gt;
&lt;/blockquote&gt; &lt;blockquote&gt; 
&lt;p&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; int itemsGiven
= 0;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; foreach (T t in
yielder)&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
itemsGiven++;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
yield return t;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; } 
&lt;/p&gt;
&lt;/blockquote&gt; &lt;blockquote&gt; 
&lt;p&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (itemsGiven
== 0)&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
break;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br&gt;
}
&lt;/p&gt;
&lt;/blockquote&gt; 
&lt;p&gt;
This can be used to return a stream of "tasks bulk" :
&lt;/p&gt;
&lt;blockquote&gt; 
&lt;p&gt;
Yield.Bulked&amp;lt;Task&amp;gt;(delegate { return tasksRepository.Dequeue(1000); }) // return
the &lt;strong&gt;next&lt;/strong&gt; 1000 from the 100,000,000 items queue until no more tasks
exists in the repository.
&lt;/p&gt;
&lt;/blockquote&gt; &lt;blockquote&gt; 
&lt;p&gt;
&lt;strong&gt;Important note&lt;/strong&gt;: 
&lt;br&gt;
In this scenario, we should return 1000 items from Dequeue method &lt;strong&gt;without&lt;/strong&gt; using
yield to avoid holding expensive resources for long period of time (as discussed).&lt;br&gt;
Once we have those 1000 items, we can yield each one of them to the caller (very cheap,
no resources are used).
&lt;/p&gt;
&lt;/blockquote&gt; 
&lt;p&gt;
Finally, we can execute billions of tasks in parallel via SpawnEnumerator:
&lt;/p&gt;
&lt;blockquote&gt; 
&lt;p&gt;
IEnumerator&amp;lt;Task&amp;gt; tasksEnumerator = Yield.Bulked&amp;lt;Task&amp;gt;(delegate { return
tasksRepository.Dequeue(1000); });&lt;br&gt;
Action&amp;lt;Task&amp;gt; taskHandler = delegate(Task t) { /* execute single task */ }; 
&lt;/p&gt;
&lt;/blockquote&gt; &lt;blockquote&gt; 
&lt;p&gt;
// execute the tasks in parallel, using 50 threads and holding ~1000 items in memory.&lt;br&gt;
_tasksExecutor = SpawnEnumerator&amp;lt;Task&amp;gt;.Start(50, "mypool", 1000, tasksEnumerator,
taskHandler); 
&lt;p&gt;
// note:don't forget to dispose _tasksExecutor when killing/stopping app!
&lt;/p&gt;
&lt;/blockquote&gt; 
&lt;p&gt;
&lt;br&gt;
Using Yield.Bulked guarantees that we won't hold expensive resources for too long
while allowing us to generate a "stream" of Tasks to run in parallel.&lt;br&gt;
The code is easy to read and follow (I hope) and we gain a simple method for executing
billions of tasks very effectively (CPU &amp;amp; memory wise).
&lt;/p&gt;
&lt;img width="0" height="0" src="http://lnbogen.com/aggbug.ashx?id=5dd36c56-0901-490b-a137-268871050d92" /&gt;</description>
      <comments>http://lnbogen.com/CommentView,guid,5dd36c56-0901-490b-a137-268871050d92.aspx</comments>
    </item>
    <item>
      <trackback:ping>http://lnbogen.com/Trackback.aspx?guid=bc44ca02-60c1-4593-a0fe-7856625fe0e7</trackback:ping>
      <pingback:server>http://lnbogen.com/pingback.aspx</pingback:server>
      <pingback:target>http://lnbogen.com/PermaLink,guid,bc44ca02-60c1-4593-a0fe-7856625fe0e7.aspx</pingback:target>
      <dc:creator>Oren Ellenbogen</dc:creator>
      <wfw:comment>http://lnbogen.com/CommentView,guid,bc44ca02-60c1-4593-a0fe-7856625fe0e7.aspx</wfw:comment>
      <wfw:commentRss>http://lnbogen.com/SyndicationService.asmx/GetEntryCommentsRss?guid=bc44ca02-60c1-4593-a0fe-7856625fe0e7</wfw:commentRss>
      <slash:comments>3</slash:comments>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
How many of you played with <a href="http://msdn.microsoft.com/en-us/library/9k7k7cf0.aspx">C#
yield statement</a> ? I guess that most of you did. 
<br />
Anyway, like most of the MSDN examples out there, when used incorrectly, it could
introduce <em>very</em> bad behavior to your code. Consider the following:
</p>
        <p>
public IEnumerable&lt;User&gt; GetUsers(int count)<br />
{<br />
    using (MysqlConnection connection = new MysqlConnection("..."))<br />
    {<br />
        // MysqlDataReader reader = create an MysqlCommand
and execute it<br />
        while (reader.Read())<br />
            yield return new
User(/*... fill parameters from the reader ... */);<br />
    }<br />
} 
</p>
        <p>
Looks pretty harmless right? Not quite. The yield statement is actually transformed
to a "state machine" which means that every time we yield a result back to the client
(the caller of GetUsers in our example), we <strong>wait</strong> for the client to
call to the next item (via IEnumerator&lt;T&gt;.MoveNext()). <strong>The code above
will hold the connection open until the client done iterating all of the User items</strong>.
This will lead into major scalability issues very quickly! You should always keep
your DB connections open for short period to prevent connection exhaustion (threads
waiting for available DB connection in the pool for long period, until timeout). Because
yield returns the control <strong>to the caller</strong>, it might be that the caller
will "take his time" thus leading to connection exhaustion.
</p>
        <p>
          <br />
On the other hand, used wisely and <em>yield</em> yields (lame joke, sorry) <em>HUGE</em> benefits:<br />
[note: code written in notepad, stupidity won't compile]
</p>
        <ul>
          <li>
            <strong>Avoid <em>useless</em> memory allocations</strong>
          </li>
        </ul>
        <blockquote>
          <p>
            <strong>#1:</strong>
            <br />
How many times you end up creating something like this:
</p>
          <p>
    public List&lt;T&gt; Filter(List&lt;T&gt; input, Predicate&lt;T&gt;
predicate)<br />
    {<br />
       List&lt;T&gt; output = new List&lt;T&gt;(input.Count
/2);<br />
       foreach (T item in input)<br />
          if (predicate(item))<br />
             output.Add(item); 
</p>
          <p>
       return output;<br />
   } 
</p>
          <p>
We allocate much more memory than we need only to hold the output during the calculation.
A better approach will be:
</p>
          <p>
    public IEnumerator&lt;T&gt; Filter(IEnumerator&lt;T&gt; input,
Predicate&lt;T&gt; predicate)<br />
    {<br />
       foreach (T item in input)<br />
          if (predicate(item))<br />
             yield return
item;<br />
   }
</p>
          <p>
This way we allocate only <strong>one</strong> T at a time (will be saved in the generated
state machine). In addition, the client could choose to send each item via yield as
well, thus saving the need to create the "input" before calling our Filter method.
</p>
          <p>
            <strong>
              <br />
#2:</strong>
            <br />
Another oh-(gosh-why)-so-common example is the following:
</p>
          <p>
public void Save(T item)<br />
{<br />
    Save(new T[] { item });<br />
} 
</p>
          <p>
public void Save(ICollection&lt;T&gt; items)<br />
{<br />
    // do your magic here to save items<br />
} 
</p>
          <p>
Assuming you call Save with a single item quite a lot, you're allocating <strong>A
LOT</strong> of memory to create one-item arrays. A better approach will be:
</p>
          <p>
public void Save(T item)<br />
{<br />
    Save(Yield.One(item));<br />
} 
</p>
          <p>
public void Save(IEnumerator&lt;T&gt; items)<br />
{<br />
    // do your magic here to save items<br />
} 
</p>
          <p>
public static class Yield<br />
{<br />
    public static IEnumerator&lt;T&gt; One&lt;T&gt;(T item)<br />
    {<br />
        yield item;<br />
    }<br />
} 
</p>
          <p>
~Zero memory allocation here.
</p>
        </blockquote>
        <ul>
          <li>
            <strong>Avoid "impossible" memory allocation</strong>
          </li>
        </ul>
        <blockquote>
          <p>
Let's say you want to read a 20G file with emails where every line holds a single
email. Trying to declare a List&lt;string&gt; and filling it up will make your memory
blow up obviously. You simply can't hold that much in memory. Instead, you can use
Stream.ReadLine and yield back each row to your client, until all of the emails are
taken care of. Yes, you can try to read the file in chunks (keeping a pointer), but
this is exactly what yield does under the hood. Reminder: DRY principle is gold (or
Don't Repeat .Net Framework, in our case).
</p>
        </blockquote>
        <ul>
          <li>
            <strong>Execute synchronous</strong>
            <strong>code asynchronously</strong> (nicely
achieved via <a href="http://msdn.microsoft.com/en-us/magazine/cc163556.aspx">CCR</a>)</li>
        </ul>
        <blockquote>
          <p>
A bit advanced, but you can read all about it <a href="http://msdn.microsoft.com/en-us/library/bb648753.aspx">here</a>.
The great benefit is you can transform (almost) any "yield based" code to run async,
if needed/wanted.
</p>
        </blockquote>
        <p>
          <strong>
            <br />
Recap:<br /></strong>Prefer using the yield statement as long as calculating values doesn't require <strong>holding</strong> an
expensive resource like a DB connection, or a FileHandler for <strong>long period
of time</strong>.
</p>
        <img width="0" height="0" src="http://lnbogen.com/aggbug.ashx?id=bc44ca02-60c1-4593-a0fe-7856625fe0e7" />
      </body>
      <title>The beauty of yield statement</title>
      <guid isPermaLink="false">http://lnbogen.com/PermaLink,guid,bc44ca02-60c1-4593-a0fe-7856625fe0e7.aspx</guid>
      <link>http://lnbogen.com/2008/10/18/TheBeautyOfYieldStatement.aspx</link>
      <pubDate>Sat, 18 Oct 2008 22:35:26 GMT</pubDate>
      <description>&lt;p&gt;
How many of you played with &lt;a href="http://msdn.microsoft.com/en-us/library/9k7k7cf0.aspx"&gt;C#
yield statement&lt;/a&gt; ? I guess that most of you did. 
&lt;br&gt;
Anyway, like most of the MSDN examples out there, when used incorrectly, it could
introduce &lt;em&gt;very&lt;/em&gt; bad behavior to your code. Consider the following:
&lt;/p&gt;
&lt;p&gt;
public IEnumerable&amp;lt;User&amp;gt; GetUsers(int count)&lt;br&gt;
{&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; using (MysqlConnection connection = new MysqlConnection("..."))&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // MysqlDataReader reader = create an MysqlCommand
and execute it&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; while (reader.Read())&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; yield return new
User(/*... fill parameters from the reader ... */);&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br&gt;
} 
&lt;p&gt;
Looks pretty harmless right? Not quite. The yield statement is actually transformed
to a "state machine" which means that every time we yield a result back to the client
(the caller of GetUsers in our example), we &lt;strong&gt;wait&lt;/strong&gt; for the client to
call to the next item (via IEnumerator&amp;lt;T&amp;gt;.MoveNext()). &lt;strong&gt;The code above
will hold the connection open until the client done iterating all of the User items&lt;/strong&gt;.
This will lead into major scalability issues very quickly! You should always keep
your DB connections open for short period to prevent connection exhaustion (threads
waiting for available DB connection in the pool for long period, until timeout). Because
yield returns the control &lt;strong&gt;to the caller&lt;/strong&gt;, it might be that the caller
will "take his time" thus leading to connection exhaustion.
&lt;/p&gt;
&lt;p&gt;
&lt;br&gt;
On the other hand, used wisely and &lt;em&gt;yield&lt;/em&gt; yields (lame joke, sorry) &lt;em&gt;HUGE&lt;/em&gt; benefits:&lt;br&gt;
[note: code written in notepad, stupidity won't compile]
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Avoid &lt;em&gt;useless&lt;/em&gt; memory allocations&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt; 
&lt;p&gt;
&lt;strong&gt;#1:&lt;/strong&gt;
&lt;br&gt;
How many times you end up creating something like this:
&lt;/p&gt;
&lt;p&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; public List&amp;lt;T&amp;gt; Filter(List&amp;lt;T&amp;gt; input, Predicate&amp;lt;T&amp;gt;
predicate)&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; List&amp;lt;T&amp;gt; output = new List&amp;lt;T&amp;gt;(input.Count
/2);&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; foreach (T item in input)&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (predicate(item))&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; output.Add(item); 
&lt;/p&gt;
&lt;p&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return output;&lt;br&gt;
&amp;nbsp;&amp;nbsp; } 
&lt;p&gt;
We allocate much more memory than we need only to hold the output during the calculation.
A better approach will be:
&lt;/p&gt;
&lt;p&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; public IEnumerator&amp;lt;T&amp;gt; Filter(IEnumerator&amp;lt;T&amp;gt; input,
Predicate&amp;lt;T&amp;gt; predicate)&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; foreach (T item in input)&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (predicate(item))&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; yield return
item;&lt;br&gt;
&amp;nbsp;&amp;nbsp; }
&lt;/p&gt;
&lt;p&gt;
This way we allocate only &lt;strong&gt;one&lt;/strong&gt; T at a time (will be saved in the generated
state machine). In addition, the client could choose to send each item via yield as
well, thus saving the need to create the "input" before calling our Filter method.
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;
&lt;br&gt;
#2:&lt;/strong&gt;
&lt;br&gt;
Another oh-(gosh-why)-so-common example is the following:
&lt;/p&gt;
&lt;p&gt;
public void Save(T item)&lt;br&gt;
{&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; Save(new T[] { item });&lt;br&gt;
} 
&lt;p&gt;
public void Save(ICollection&amp;lt;T&amp;gt; items)&lt;br&gt;
{&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; // do your magic here to save items&lt;br&gt;
} 
&lt;p&gt;
Assuming you call Save with a single item quite a lot, you're allocating &lt;strong&gt;A
LOT&lt;/strong&gt; of memory to create one-item arrays. A better approach will be:
&lt;/p&gt;
&lt;p&gt;
public void Save(T item)&lt;br&gt;
{&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; Save(Yield.One(item));&lt;br&gt;
} 
&lt;p&gt;
public void Save(IEnumerator&amp;lt;T&amp;gt; items)&lt;br&gt;
{&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; // do your magic here to save items&lt;br&gt;
} 
&lt;p&gt;
public static class Yield&lt;br&gt;
{&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; public static IEnumerator&amp;lt;T&amp;gt; One&amp;lt;T&amp;gt;(T item)&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; yield item;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br&gt;
} 
&lt;p&gt;
~Zero memory allocation here.
&lt;/p&gt;
&lt;/blockquote&gt; 
&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Avoid "impossible" memory allocation&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt; 
&lt;p&gt;
Let's say you want to read a 20G file with emails where every line holds a single
email. Trying to declare a List&amp;lt;string&amp;gt; and filling it up will make your memory
blow up obviously. You simply can't hold that much in memory. Instead, you can use
Stream.ReadLine and yield back each row to your client, until all of the emails are
taken care of. Yes, you can try to read the file in chunks (keeping a pointer), but
this is exactly what yield does under the hood. Reminder: DRY principle is gold (or
Don't Repeat .Net Framework, in our case).
&lt;/p&gt;
&lt;/blockquote&gt; 
&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Execute synchronous&lt;/strong&gt; &lt;strong&gt;code asynchronously&lt;/strong&gt; (nicely
achieved via &lt;a href="http://msdn.microsoft.com/en-us/magazine/cc163556.aspx"&gt;CCR&lt;/a&gt;)&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt; 
&lt;p&gt;
A bit advanced, but you can read all about it &lt;a href="http://msdn.microsoft.com/en-us/library/bb648753.aspx"&gt;here&lt;/a&gt;.
The great benefit is you can transform (almost) any "yield based" code to run async,
if needed/wanted.
&lt;/p&gt;
&lt;/blockquote&gt; 
&lt;p&gt;
&lt;strong&gt;
&lt;br&gt;
Recap:&lt;br&gt;
&lt;/strong&gt;Prefer using the yield statement as long as calculating values doesn't require &lt;strong&gt;holding&lt;/strong&gt; an
expensive resource like a DB connection, or a FileHandler for &lt;strong&gt;long period
of time&lt;/strong&gt;.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://lnbogen.com/aggbug.ashx?id=bc44ca02-60c1-4593-a0fe-7856625fe0e7" /&gt;</description>
      <comments>http://lnbogen.com/CommentView,guid,bc44ca02-60c1-4593-a0fe-7856625fe0e7.aspx</comments>
    </item>
    <item>
      <trackback:ping>http://lnbogen.com/Trackback.aspx?guid=dba7a00e-808e-4bd7-9dd1-eb028d187db2</trackback:ping>
      <pingback:server>http://lnbogen.com/pingback.aspx</pingback:server>
      <pingback:target>http://lnbogen.com/PermaLink,guid,dba7a00e-808e-4bd7-9dd1-eb028d187db2.aspx</pingback:target>
      <dc:creator>Oren Ellenbogen</dc:creator>
      <wfw:comment>http://lnbogen.com/CommentView,guid,dba7a00e-808e-4bd7-9dd1-eb028d187db2.aspx</wfw:comment>
      <wfw:commentRss>http://lnbogen.com/SyndicationService.asmx/GetEntryCommentsRss?guid=dba7a00e-808e-4bd7-9dd1-eb028d187db2</wfw:commentRss>
      <slash:comments>1</slash:comments>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
It seems that there are MANY ways to perform http web request poorly. This is a huge
problem in today's world where web-services are more common than <a href="http://www.google.co.il/url?sa=t&amp;source=web&amp;ct=res&amp;cd=3&amp;url=http%3A%2F%2Fwww.marketoracle.co.uk%2FArticle6749.html&amp;ei=YbP0SJ7XHJfuwwGygOnUDg&amp;usg=AFQjCNFSfskKYI7noMHYim0BcSvcrFA47g&amp;sig2=5-xiW6L0aL8bzJOewhrVrw">bankrupt
banks</a>. Here is a quick pattern of how to do it right:
</p>
        <p>
public string Fetch(Uri requestUri)<br />
{
</p>
        <blockquote>
          <p>
HttpWebRequest webRequest = (HttpWebRequest)WebRequest.Create(requestUri);
</p>
        </blockquote>
        <blockquote>
          <p>
webRequest.Timeout = <strong>requestConnectTimeoutInMs</strong>; // take timeout from
config<br />
webRequest.ReadWriteTimeout = <strong>requestReadWriteTimeoutInMs</strong>; // take
timeout from config
</p>
        </blockquote>
        <blockquote>
          <p>
            <strong>using</strong> (WebResponse webResponse = webRequest.GetResponse())<br /><strong>using</strong> (StreamReader streamReader = new StreamReader(new <strong>TimeoutStream</strong>(webResponse.GetResponseStream(), <strong>fetchTimeoutInMs</strong>))
// take timeout from config<br />
     return streamReader.ReadToEnd();
</p>
        </blockquote>
        <p>
}
</p>
        <p>
          <strong>Details:</strong>
        </p>
        <ol>
          <li>
Setting Timeout property: to make sure we don't wait the default 100 seconds for "ACK"
from the server. WAY too much.</li>
          <li>
Setting ReadWriteTimeout: This is crucial to understand. StreamReader under the hood
read data in chunks, this timeout determine how much time you should wait for reading
a <em>single chunk</em>. 100 seconds, the default value, is again WAY too much.</li>
          <li>
Using TimeoutStream (you need to implement your own or let me know if you're interested
and I'll send it to you): Alright, let's say you're willing to wait for 500ms for
ACK (Timeout), up to 500ms for reading every chunk (ReadWriteTimeout) but not more
than 5 seconds for the <em>entire read</em> to complete. There is no way to achieve
it without TimeoutStream. It will start a timer internally and override Seek/Read/Write
(etc) method by checking the timer <strong>before</strong> calling the internal stream
method. TimeoutStream is a very simple wrapper around Stream. For example:</li>
        </ol>
        <p>
   public override int Read(byte[] buffer, int offset, int count)<br />
      {<br />
          CheckTimeout(); // throw TimeoutException
if timeout was reached<br />
          return _stream.Read(buffer,
offset, count);<br />
      }
</p>
        <p>
          <strong>Multiple HttpWebRequest limitation:<br /></strong>By default, you can't perform more than 2-3 async HttpWebRequest (depends
on the OS). In order to override it (the easiest way, IMHO) don't forget to add this
under &lt;configuration&gt; section in the application's config file:
</p>
        <p>
&lt;system.net&gt;<br />
  &lt;connectionManagement&gt;<br />
     &lt;add address="*" maxconnection="65000" /&gt;<br />
  &lt;/connectionManagement&gt;<br />
&lt;/system.net&gt;<br /><strong><br />
Why should you follow these guidelines:</strong></p>
        <ol>
          <li>
Never trust 3rd party components: avoid excuses like "my site is not responsive because
1000 threads are waiting for web-service-X to respond". By setting those parameters
you're safe to make your own choices of how much time to wait. Log and monitor these
things to adjust your application and alert your suppliers.</li>
          <li>
Be able to determine your own SLA for the world: again, if internally you need to
call a web-service, make sure you're able to control the time you're willing to spend.
You've got clients to serve and they want you to meet the SLA as you promised! 
</li>
        </ol>
        <p>
          <strong>Important note about recycling HttpWebRequest.GetResposne()<br /></strong>Simply put, it's not working <em>by design</em>. That means that if you fail
to get a response on time (due to 1,2 or 3), don't call the webRequest.GetResponse()
again as it is cached internally (you'll get the same HttpWebResposne). What you should
do is to re-create the HttpWebRequest and try again. I don't agree with the selected
design by Microsoft for this method, but at least it's good to be aware of it.
</p>
        <p>
   from <a href="http://msdn.microsoft.com/en-us/library/system.net.httpwebrequest.getresponse.aspx">MSDN</a>: 
</p>
        <p>
   " Multiple calls to GetResponse return the same response object; the
request is not reissued. " 
</p>
        <p>
          <strong>Final note:<br /></strong>You should obviously consider writing a HttpWebRequestHelper class (or extension
method) and use it instead of copy&amp;paste this code all over your codebase.
</p>
        <img width="0" height="0" src="http://lnbogen.com/aggbug.ashx?id=dba7a00e-808e-4bd7-9dd1-eb028d187db2" />
      </body>
      <title>HttpWebRequest, avoiding the pitfalls</title>
      <guid isPermaLink="false">http://lnbogen.com/PermaLink,guid,dba7a00e-808e-4bd7-9dd1-eb028d187db2.aspx</guid>
      <link>http://lnbogen.com/2008/10/14/HttpWebRequestAvoidingThePitfalls.aspx</link>
      <pubDate>Tue, 14 Oct 2008 15:32:25 GMT</pubDate>
      <description>&lt;p&gt;
It seems that there are MANY ways to perform http web request poorly. This is a huge
problem in today's world where web-services are more common than &lt;a href="http://www.google.co.il/url?sa=t&amp;amp;source=web&amp;amp;ct=res&amp;amp;cd=3&amp;amp;url=http%3A%2F%2Fwww.marketoracle.co.uk%2FArticle6749.html&amp;amp;ei=YbP0SJ7XHJfuwwGygOnUDg&amp;amp;usg=AFQjCNFSfskKYI7noMHYim0BcSvcrFA47g&amp;amp;sig2=5-xiW6L0aL8bzJOewhrVrw"&gt;bankrupt
banks&lt;/a&gt;. Here is a quick pattern of how to do it right:
&lt;/p&gt;
&lt;p&gt;
public string Fetch(Uri requestUri)&lt;br&gt;
{
&lt;/p&gt;
&lt;blockquote&gt; 
&lt;p&gt;
HttpWebRequest webRequest = (HttpWebRequest)WebRequest.Create(requestUri);
&lt;/p&gt;
&lt;/blockquote&gt; &lt;blockquote&gt; 
&lt;p&gt;
webRequest.Timeout = &lt;strong&gt;requestConnectTimeoutInMs&lt;/strong&gt;; // take timeout from
config&lt;br&gt;
webRequest.ReadWriteTimeout = &lt;strong&gt;requestReadWriteTimeoutInMs&lt;/strong&gt;; // take
timeout from config
&lt;/p&gt;
&lt;/blockquote&gt; &lt;blockquote&gt; 
&lt;p&gt;
&lt;strong&gt;using&lt;/strong&gt; (WebResponse webResponse = webRequest.GetResponse())&lt;br&gt;
&lt;strong&gt;using&lt;/strong&gt; (StreamReader streamReader = new StreamReader(new &lt;strong&gt;TimeoutStream&lt;/strong&gt;(webResponse.GetResponseStream(), &lt;strong&gt;fetchTimeoutInMs&lt;/strong&gt;))
// take timeout from config&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return streamReader.ReadToEnd();
&lt;/p&gt;
&lt;/blockquote&gt; 
&lt;p&gt;
}
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;Details:&lt;/strong&gt;
&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
Setting Timeout property: to make sure we don't wait the default 100 seconds for "ACK"
from the server. WAY too much.&lt;/li&gt;
&lt;li&gt;
Setting ReadWriteTimeout: This is crucial to understand. StreamReader under the hood
read data in chunks, this timeout determine how much time you should wait for reading
a &lt;em&gt;single chunk&lt;/em&gt;. 100 seconds, the default value, is again WAY too much.&lt;/li&gt;
&lt;li&gt;
Using TimeoutStream (you need to implement your own or let me know if you're interested
and I'll send it to you): Alright, let's say you're willing to wait for 500ms for
ACK (Timeout), up to 500ms for reading every chunk (ReadWriteTimeout) but not more
than 5 seconds for the &lt;em&gt;entire read&lt;/em&gt; to complete. There is no way to achieve
it without TimeoutStream. It will start a timer internally and override Seek/Read/Write
(etc) method by checking the timer &lt;strong&gt;before&lt;/strong&gt; calling the internal stream
method. TimeoutStream is a very simple wrapper around Stream. For example:&lt;/li&gt;
&lt;p&gt;
&amp;nbsp;&amp;nbsp; public override int Read(byte[] buffer, int offset, int count)&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; CheckTimeout(); // throw TimeoutException
if timeout was reached&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return _stream.Read(buffer,
offset, count);&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }
&lt;/p&gt;
&gt;
&lt;p&gt;
&lt;strong&gt;Multiple HttpWebRequest limitation:&lt;br&gt;
&lt;/strong&gt;By default, you can't perform more than 2-3 async HttpWebRequest (depends
on the OS). In order to override it (the easiest way, IMHO) don't forget to add this
under &amp;lt;configuration&amp;gt; section in the application's config file:
&lt;/p&gt;
&lt;p&gt;
&amp;lt;system.net&amp;gt;&lt;br&gt;
&amp;nbsp; &amp;lt;connectionManagement&amp;gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;add address="*" maxconnection="65000" /&amp;gt;&lt;br&gt;
&amp;nbsp; &amp;lt;/connectionManagement&amp;gt;&lt;br&gt;
&amp;lt;/system.net&amp;gt;&lt;br&gt;
&lt;strong&gt;
&lt;br&gt;
Why should you follow these guidelines:&lt;/strong&gt; 
&lt;ol&gt;
&lt;li&gt;
Never trust 3rd party components: avoid excuses like "my site is not responsive because
1000 threads are waiting for web-service-X to respond". By setting those parameters
you're safe to make your own choices of how much time to wait. Log and monitor these
things to adjust your application and alert your suppliers.&lt;/li&gt;
&lt;li&gt;
Be able to determine your own SLA for the world: again, if internally you need to
call a web-service, make sure you're able to control the time you're willing to spend.
You've got clients to serve and they want you to meet the SLA as you promised! 
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;
&lt;strong&gt;Important note about recycling HttpWebRequest.GetResposne()&lt;br&gt;
&lt;/strong&gt;Simply put, it's not working &lt;em&gt;by design&lt;/em&gt;. That means that if you fail
to get a response on time (due to 1,2 or 3), don't call the webRequest.GetResponse()
again as it is cached internally (you'll get the same HttpWebResposne). What you should
do is to re-create the HttpWebRequest and try again. I don't agree with the selected
design by Microsoft for this method, but at least it's good to be aware of it.
&lt;/p&gt;
&lt;p&gt;
&amp;nbsp;&amp;nbsp; from &lt;a href="http://msdn.microsoft.com/en-us/library/system.net.httpwebrequest.getresponse.aspx"&gt;MSDN&lt;/a&gt;: 
&lt;p&gt;
&amp;nbsp;&amp;nbsp; " Multiple calls to GetResponse return the same response object; the
request is not reissued. " 
&lt;p&gt;
&lt;strong&gt;Final note:&lt;br&gt;
&lt;/strong&gt;You should obviously consider writing a HttpWebRequestHelper class (or extension
method) and use it instead of copy&amp;amp;paste this code all over your codebase.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://lnbogen.com/aggbug.ashx?id=dba7a00e-808e-4bd7-9dd1-eb028d187db2" /&gt;</description>
      <comments>http://lnbogen.com/CommentView,guid,dba7a00e-808e-4bd7-9dd1-eb028d187db2.aspx</comments>
    </item>
    <item>
      <trackback:ping>http://lnbogen.com/Trackback.aspx?guid=40072280-5777-4723-b001-51f1b086cd3d</trackback:ping>
      <pingback:server>http://lnbogen.com/pingback.aspx</pingback:server>
      <pingback:target>http://lnbogen.com/PermaLink,guid,40072280-5777-4723-b001-51f1b086cd3d.aspx</pingback:target>
      <dc:creator>Oren Ellenbogen</dc:creator>
      <wfw:comment>http://lnbogen.com/CommentView,guid,40072280-5777-4723-b001-51f1b086cd3d.aspx</wfw:comment>
      <wfw:commentRss>http://lnbogen.com/SyndicationService.asmx/GetEntryCommentsRss?guid=40072280-5777-4723-b001-51f1b086cd3d</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
[ <a href="http://www.lnbogen.com/Part1SpawnEnumeratorDealingWithBillionsOfIndependentItems.aspx">Part
1</a>, this is <a href="http://www.lnbogen.com/Part2SpawnEnumeratorDealingWithBillionsOfIndependentItems.aspx">Part
2</a>, <a href="http://www.lnbogen.com/Part3SpawnEnumeratorDealingWithBillionsOfIndependentItems.aspx">Part
3</a> ]
</p>
        <p>
In <a href="http://www.lnbogen.com/Part1SpawnEnumeratorDealingWithBillionsOfIndependentItems.aspx">Part
1</a> I've talked about the general notions behind SpawnEnumerator and played with
the API. If you're not familiar with Microsoft's CCR, this post might require a 2nd
&amp; 3rd read to understand completely. CCR changed the way you should think or address
async code. It's a game worth playing and studying the rules is only for your advantage.
Alright, enough chit chat, let's make it happen (complete code attached at the end).<br /><br /><strong>Class definition:</strong></p>
        <p>
  public sealed class SpawnEnumerator&lt;T&gt; : IDisposable<br />
       private SpawnEnumerator(int threadsCount, string
threadsPoolName, IEnumerator&lt;T&gt; filler) { /* initialize fields by parameters,
nothing more */ }
</p>
        <p>
          <strong>Now, let's have a look at <em>some</em> of the fields: </strong>
        </p>
        <p>
  private const double DefaultLowThresholdPrcentage = 0.1; // When "items to
process" queue reach 10%, we want to re-fill. Should be exposed of course.
</p>
        <p>
  private event Action&lt;DateTime&gt; _enumeratorDepleted = delegate { }; //
trigger when the enumerator is empty<br />
  private event Action&lt;DateTime&gt; _allTasksAreCompleted = delegate { };
// trigger when all tasks are completed
</p>
        <p>
  private readonly Dispatcher _dispatcher; // our "threadpool"<br />
  private readonly DispatcherQueue _dispatcherQueue; // hold actual ITask, waiting
for the dispatcher (aka worker threads) to handle them. more about it soon. 
</p>
        <p>
  private readonly Port&lt;T&gt; _itemsToProcessPort;  // hold wannabe tasks,
currently a queue of items of T we want to process. 
<br />
  private readonly Port&lt;EmptyValue&gt; _itemCompleteNotificationPort; // soon...<br />
  private readonly Port&lt;EmptyValue&gt; _initializePort;  // soon... 
</p>
        <p>
  private readonly IEnumerator&lt;T&gt; _enumerator; // the enumerator we'll
use to fill the _itemsToProcessPort
</p>
        <p>
          <strong>Deeper look on what we have so far:</strong>
        </p>
        <ul>
          <li>
_itemsToProcessPort: will act as the queue of items we want to process. In CCR's world,
Port&lt;T&gt; is actually a "smart queue" (more on it later). 
</li>
          <li>
_itemCompleteNotificationPort: will be used to notify on every <em>completed item</em>.
Assuming that we need to fill 100 items to the port, and our lower limit is 10%, we
want to re-fill the _itemsToProcessPort every 90 completed items. Notice we're using
EmptyValue as T. EmptyValue is a CCR type that holds EmptyValue.SharedInstance to
avoid memory allocation. 
</li>
          <li>
_initializePort: will be used to initialize the _itemsToProcessPort with the 1st bulk
of items. 
</li>
        </ul>
        <p>
          <strong>Step back, what's going on?!!? why so many Port ?</strong>
          <br />
Well, the idea behind CCR is all about <em>messaging</em>. You can pass messages to
ports (Port&lt;T&gt; is thread-safe of course) and by doing so, you can take advantage
of the "smart queue" implementation behind Port&lt;T&gt;. When posting a message to
a port, the CCR will try to apply some "predicates" on the port and if a "predicate"
returns true, it will dequeue the item(s) from the Port matched that "predicate",
create an ITask of it and push it into the DispatcherQueue as an "actual task". 
</p>
        <p>
Using Ports makes it easier for us to define complex async code. instead of putting
locks all over the place, I can simply post a message to _itemCompleteNotificationPort
and after X messages posted to this port, ask to re-fill the queue when a thread is
available. This is much easier then counting each completed item and if ((counter
% X) == 0), lock some object and re-fill. Both will work, but using the CCR world
you don't have to think about <strong>technical async problems/solutions</strong> but
rather on the <strong>logical async operations</strong> you want to perform. You'll
write much less code, zero locks <em>of your own</em> and mostly think about "this
could run concurrently", "this must run exclusively" and let the CCR schedule everything
for you. 
</p>
        <p>
          <strong>Start method:</strong> (as discussed in Part 1)<br />
public static SpawnEnumerator&lt;T&gt; Start(int threadsCount, string threadsPoolName,
int upperQueueSize, IEnumerable&lt;T&gt; filler, Action&lt;T&gt; handler)<br />
{<br />
  // .. validate parameters, nothing interesting... 
<br />
  SpawnEnumerator&lt;T&gt; sw = new SpawnEnumerator&lt;T&gt;(threadsCount, threadsPoolName,
filler.GetEnumerator());<br />
  sw.Initialize(handler, upperQueueSize); 
<br />
  return sw;<br />
}
</p>
        <p>
          <strong>API Design: Why Start method with private constructor instead of public constructor
alone:</strong>
          <br />
The client of this method should understand that once she supply the arguments, things
will start happening - we'll immediately start to process items from the enumerator.
You'll soon find out that Start is non-blocking method. This "Start" method, so I
feel, make it's it more explicit as it should be. 
</p>
        <p>
          <strong>Initialize method:</strong>
          <br />
private void Initialize(Action&lt;T&gt; handler, int upperQueueSize)<br />
{<br />
  RegisterRecievers(handler, upperQueueSize); // where CCR *<em>magic</em>* happens.
soon...<br />
  _initializePort.Post(EmptyValue.SharedInstance); // post a message to let "someone"
know we want to fill the 1st bulk of items<br />
}
</p>
        <p>
          <strong>RegisterRecievers method:<br /></strong>Before we look at the code, here is a remainder of the main things we want
to accomplish:
</p>
        <ol>
          <li>
We should fill the _itemsToProcessPort for the 1st bulk or once we reach the lower
limit of the queue, by counting how many items were completed. Keeping in mind that
_enumerator is not thread-safe and we don't want to start locking access to it <em>on
our own</em>, we should make sure that re-filling is done <strong>exclusively</strong> from
1 thread only. 
</li>
          <li>
We want to handle each one of the items posted to _itemsToProcessPort with the supplied
"handler" (given in Start method). Each item is independent so obviously we want to
process each item <strong>concurrently</strong>, according to the amount of threads
in the Dispatcher.</li>
        </ol>
        <p>
private void RegisterRecievers(Action&lt;T&gt; handler, int upperQueueSize)<br />
{<br />
  int numberOfItemsToDepleteBeforePushingNewBulk = (int)Math.Ceiling((1 - DefaultLowThresholdPrcentage)
* upperQueueSize); 
</p>
        <p>
  Arbiter.Activate(_dispatcherQueue, 
</p>
        <p>
     Arbiter.Interleave(<br />
         new TeardownReceiverGroup(),// nothing
here<br />
         new ExclusiveReceiverGroup(<br />
               
// 1st bulk:<br />
               
Arbiter.Receive(false, _initializePort, delegate { FillItemsToProcessQueueWithNextBulk(upperQueueSize);
}), // only once, that's why the "false" is here.<br /><br />
               
// enough items were completed which means "items to process" queue reached lower
limit:<br />
               
Arbiter.MultipleItemReceive(true, _itemCompleteNotificationPort, numberOfItemsToDepleteBeforePushingNewBulk, 
<br />
                                         
delegate { FillItemsToProcessQueueWithNextBulk(upperQueueSize); })<br />
            ),<br />
         new ConcurrentReceiverGroup(<br />
               
// process items concurrently<br />
               
Arbiter.Receive(true, _itemsToProcessPort, // listen to <em>every</em> post, that's
why the "true"<br />
                    
delegate(T item)<br />
                    
{<br />
                        
try<br />
                        
{<br />
                            
handler(item); 
<br />
                        
}<br />
                        
catch (Exception err) { /* log error */ }<br />
                        
finally<br />
                        
{<br />
                            
HandleCompletedItem();<br />
                        
}<br />
                    
})<br />
            )<br />
        )<br />
    );<br />
}
</p>
        <p>
Alright, this is a bit harder to read but let's try to simplify it by reading it from
inside-out. 
</p>
        <ul>
          <li>
Under ExclusiveReceiverGroup you'll see 2 receivers, one that listen to _initalizePort
and once a message is posted, it will create an ITask that internally (when a thread
is available) call FillItemsToProcessQueueWithNextBulk method. The second receiver
will listen to _itemCompleteNotificationPort and do the same as the first one for
every numberOfItemsToDepleteBeforePushingNewBulk items posted to the Port. 
</li>
          <li>
Under ConcurrentReceiverGroup you'll see a receiver listening to _itemsToProcessPort
and for every message it will create an ITask that internally (again, one a thread
is available) will run the given "item handler" with the item dequeued from the Port. 
</li>
          <li>
We use Arbiter.Activate(_dispatcherQueue, ...) to register each created ITask from
the receivers to the internal queue. Queue of actual tasks. 
</li>
          <li>
This method is <strong>non-blocking</strong>, we only register receivers that know
how to create and enqueue ITask from messages posted to some Port. That's it.</li>
        </ul>
        <p>
          <strong>Recap:</strong>
          <br />
We post messages to different Port&lt;T&gt; and write receivers that "listen" to the
messages based on some rules (one receiver listen to every message, one listen to
only one message, one listen to X messages etc). When the receiver's rules apply,
the CCR will dequeue all the relevant (applied the rule) messages from the Port&lt;T&gt;
and wrap them with the supplied delegated as ITask. This ITask instance will be enqueued
to the DispatcherQueue until the Dispatcher have a free thread to handle it. The Dispatcher,
according to the <strong>requested scheduling</strong> (some ITask must run exclusively,
some can run concurrently, as we've seen), will execute those tasks.
</p>
        <p>
          <br />
You can download the complete code (with some extra features) here: <a href="http://www.lnbogen.com/content/binary/SpawnEnumerator.txt">SpawnEnumerator.txt</a> (12KB)
- you'll need CCR &amp; log4net dll in order to compile it.
</p>
        <img width="0" height="0" src="http://lnbogen.com/aggbug.ashx?id=40072280-5777-4723-b001-51f1b086cd3d" />
      </body>
      <title>Part2: SpawnEnumerator, dealing with billions of independent items</title>
      <guid isPermaLink="false">http://lnbogen.com/PermaLink,guid,40072280-5777-4723-b001-51f1b086cd3d.aspx</guid>
      <link>http://lnbogen.com/2008/10/14/Part2SpawnEnumeratorDealingWithBillionsOfIndependentItems.aspx</link>
      <pubDate>Tue, 14 Oct 2008 14:07:52 GMT</pubDate>
      <description>&lt;p&gt;
[ &lt;a href="http://www.lnbogen.com/Part1SpawnEnumeratorDealingWithBillionsOfIndependentItems.aspx"&gt;Part
1&lt;/a&gt;, this is &lt;a href="http://www.lnbogen.com/Part2SpawnEnumeratorDealingWithBillionsOfIndependentItems.aspx"&gt;Part
2&lt;/a&gt;, &lt;a href="http://www.lnbogen.com/Part3SpawnEnumeratorDealingWithBillionsOfIndependentItems.aspx"&gt;Part
3&lt;/a&gt; ]
&lt;/p&gt;
&lt;p&gt;
In &lt;a href="http://www.lnbogen.com/Part1SpawnEnumeratorDealingWithBillionsOfIndependentItems.aspx"&gt;Part
1&lt;/a&gt; I've talked about the general notions behind SpawnEnumerator and played with
the API. If you're not familiar with Microsoft's CCR, this post might require a 2nd
&amp;amp; 3rd read to understand completely. CCR changed the way you should think or address
async code. It's a game worth playing and studying the rules is only for your advantage.
Alright, enough chit chat, let's make it happen (complete code attached at the end).&lt;br&gt;
&lt;br&gt;
&lt;strong&gt;Class definition:&lt;/strong&gt;
&lt;/p&gt;
&lt;p&gt;
&amp;nbsp; public sealed class SpawnEnumerator&amp;lt;T&amp;gt; : IDisposable&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; private SpawnEnumerator(int threadsCount, string
threadsPoolName, IEnumerator&amp;lt;T&amp;gt; filler) { /* initialize fields by parameters,
nothing more */ }
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;Now, let's have a look at &lt;em&gt;some&lt;/em&gt; of the fields: &lt;/strong&gt; 
&lt;p&gt;
&amp;nbsp; private const double DefaultLowThresholdPrcentage = 0.1; // When "items to
process" queue reach 10%, we want to re-fill. Should be exposed of course.
&lt;/p&gt;
&lt;p&gt;
&amp;nbsp; private event Action&amp;lt;DateTime&amp;gt; _enumeratorDepleted = delegate { }; //
trigger when the enumerator is empty&lt;br&gt;
&amp;nbsp; private event Action&amp;lt;DateTime&amp;gt; _allTasksAreCompleted = delegate { };
// trigger when all tasks are completed
&lt;/p&gt;
&lt;p&gt;
&amp;nbsp; private readonly Dispatcher _dispatcher; // our "threadpool"&lt;br&gt;
&amp;nbsp; private readonly DispatcherQueue _dispatcherQueue; // hold actual ITask, waiting
for the dispatcher (aka worker threads) to handle them. more about it soon. 
&lt;/p&gt;
&lt;p&gt;
&amp;nbsp; private readonly Port&amp;lt;T&amp;gt; _itemsToProcessPort;&amp;nbsp; // hold wannabe tasks,
currently a queue of items of T we want to process. 
&lt;br&gt;
&amp;nbsp; private readonly Port&amp;lt;EmptyValue&amp;gt; _itemCompleteNotificationPort; // soon...&lt;br&gt;
&amp;nbsp; private readonly Port&amp;lt;EmptyValue&amp;gt; _initializePort;&amp;nbsp; // soon... 
&lt;/p&gt;
&lt;p&gt;
&amp;nbsp; private readonly IEnumerator&amp;lt;T&amp;gt; _enumerator; // the enumerator we'll
use to fill the _itemsToProcessPort
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;Deeper look on what we have so far:&lt;/strong&gt; 
&lt;ul&gt;
&lt;li&gt;
_itemsToProcessPort: will act as the queue of items we want to process. In CCR's world,
Port&amp;lt;T&amp;gt; is actually a "smart queue" (more on it later). 
&lt;li&gt;
_itemCompleteNotificationPort: will be used to notify on every &lt;em&gt;completed item&lt;/em&gt;.
Assuming that we need to fill 100 items to the port, and our lower limit is 10%, we
want to re-fill the _itemsToProcessPort every 90 completed items. Notice we're using
EmptyValue as T. EmptyValue is a CCR type that holds EmptyValue.SharedInstance to
avoid memory allocation. 
&lt;li&gt;
_initializePort: will be used to initialize the _itemsToProcessPort with the 1st bulk
of items. 
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
&lt;strong&gt;Step back, what's going on?!!? why so many Port ?&lt;/strong&gt; 
&lt;br&gt;
Well, the idea behind CCR is all about &lt;em&gt;messaging&lt;/em&gt;. You can pass messages to
ports (Port&amp;lt;T&amp;gt; is thread-safe of course) and by doing so, you can take advantage
of the "smart queue" implementation behind Port&amp;lt;T&amp;gt;. When posting a message to
a port, the CCR will try to apply some "predicates" on the port and if a "predicate"
returns true, it will dequeue the item(s) from the Port matched that "predicate",
create an ITask of it and push it into the DispatcherQueue as an "actual task". 
&lt;/p&gt;
&lt;p&gt;
Using Ports makes it easier for us to define complex async code. instead of putting
locks all over the place, I can simply post a message to _itemCompleteNotificationPort
and after X messages posted to this port, ask to re-fill the queue when a thread is
available. This is much easier then counting each completed item and if ((counter
% X) == 0), lock some object and re-fill. Both will work, but using the CCR world
you don't have to think about &lt;strong&gt;technical async problems/solutions&lt;/strong&gt; but
rather on the &lt;strong&gt;logical async operations&lt;/strong&gt; you want to perform. You'll
write much less code, zero locks &lt;em&gt;of your own&lt;/em&gt; and mostly think about "this
could run concurrently", "this must run exclusively" and let the CCR schedule everything
for you. 
&lt;p&gt;
&lt;strong&gt;Start method:&lt;/strong&gt; (as discussed in Part 1)&lt;br&gt;
public static SpawnEnumerator&amp;lt;T&amp;gt; Start(int threadsCount, string threadsPoolName,
int upperQueueSize, IEnumerable&amp;lt;T&amp;gt; filler, Action&amp;lt;T&amp;gt; handler)&lt;br&gt;
{&lt;br&gt;
&amp;nbsp; // .. validate parameters, nothing interesting... 
&lt;br&gt;
&amp;nbsp; SpawnEnumerator&amp;lt;T&amp;gt; sw = new SpawnEnumerator&amp;lt;T&amp;gt;(threadsCount, threadsPoolName,
filler.GetEnumerator());&lt;br&gt;
&amp;nbsp; sw.Initialize(handler, upperQueueSize); 
&lt;br&gt;
&amp;nbsp; return sw;&lt;br&gt;
}
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;API Design: Why Start method with private constructor instead of public constructor
alone:&lt;/strong&gt; 
&lt;br&gt;
The client of this method should understand that once she supply the arguments, things
will start happening - we'll immediately start to process items from the enumerator.
You'll soon find out that Start is non-blocking method. This "Start" method, so I
feel, make it's it more explicit as it should be. 
&lt;p&gt;
&lt;strong&gt;Initialize method:&lt;/strong&gt; 
&lt;br&gt;
private void Initialize(Action&amp;lt;T&amp;gt; handler, int upperQueueSize)&lt;br&gt;
{&lt;br&gt;
&amp;nbsp; RegisterRecievers(handler, upperQueueSize); // where CCR *&lt;em&gt;magic&lt;/em&gt;* happens.
soon...&lt;br&gt;
&amp;nbsp; _initializePort.Post(EmptyValue.SharedInstance); // post a message to let "someone"
know we want to fill the 1st bulk of items&lt;br&gt;
}
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;RegisterRecievers method:&lt;br&gt;
&lt;/strong&gt;Before we look at the code, here is a remainder of the main things we want
to accomplish:
&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
We should fill the _itemsToProcessPort for the 1st bulk or once we reach the lower
limit of the queue, by counting how many items were completed. Keeping in mind that
_enumerator is not thread-safe and we don't want to start locking access to it &lt;em&gt;on
our own&lt;/em&gt;, we should make sure that re-filling is done &lt;strong&gt;exclusively&lt;/strong&gt; from
1 thread only. 
&lt;li&gt;
We want to handle each one of the items posted to _itemsToProcessPort with the supplied
"handler" (given in Start method). Each item is independent so obviously we want to
process each item &lt;strong&gt;concurrently&lt;/strong&gt;, according to the amount of threads
in the Dispatcher.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;
private void RegisterRecievers(Action&amp;lt;T&amp;gt; handler, int upperQueueSize)&lt;br&gt;
{&lt;br&gt;
&amp;nbsp; int numberOfItemsToDepleteBeforePushingNewBulk = (int)Math.Ceiling((1 - DefaultLowThresholdPrcentage)
* upperQueueSize); 
&lt;/p&gt;
&lt;p&gt;
&amp;nbsp; Arbiter.Activate(_dispatcherQueue, 
&lt;/p&gt;
&lt;p&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Arbiter.Interleave(&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; new TeardownReceiverGroup(),// nothing
here&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; new ExclusiveReceiverGroup(&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
// 1st bulk:&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
Arbiter.Receive(false, _initializePort, delegate { FillItemsToProcessQueueWithNextBulk(upperQueueSize);
}), // only once, that's why the "false" is here.&lt;br&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
// enough items were completed which means "items to process" queue reached lower
limit:&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
Arbiter.MultipleItemReceive(true, _itemCompleteNotificationPort, numberOfItemsToDepleteBeforePushingNewBulk, 
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
delegate { FillItemsToProcessQueueWithNextBulk(upperQueueSize); })&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ),&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; new ConcurrentReceiverGroup(&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
// process items concurrently&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
Arbiter.Receive(true, _itemsToProcessPort, // listen to &lt;em&gt;every&lt;/em&gt; post, that's
why the "true"&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
delegate(T item)&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
{&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
try&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
{&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
handler(item); 
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
}&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
catch (Exception err) { /* log error */ }&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
finally&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
{&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
HandleCompletedItem();&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
}&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
})&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; )&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; )&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; );&lt;br&gt;
}
&lt;/p&gt;
&lt;p&gt;
Alright, this is a bit harder to read but let's try to simplify it by reading it from
inside-out. 
&lt;ul&gt;
&lt;li&gt;
Under ExclusiveReceiverGroup you'll see 2 receivers, one that listen to _initalizePort
and once a message is posted, it will create an ITask that internally (when a thread
is available) call FillItemsToProcessQueueWithNextBulk method. The second receiver
will listen to _itemCompleteNotificationPort and do the same as the first one for
every numberOfItemsToDepleteBeforePushingNewBulk items posted to the Port. 
&lt;li&gt;
Under ConcurrentReceiverGroup you'll see a receiver listening to _itemsToProcessPort
and for every message it will create an ITask that internally (again, one a thread
is available) will run the given "item handler" with the item dequeued from the Port. 
&lt;li&gt;
We use Arbiter.Activate(_dispatcherQueue, ...) to register each created ITask from
the receivers to the internal queue. Queue of actual tasks. 
&lt;li&gt;
This method is &lt;strong&gt;non-blocking&lt;/strong&gt;, we only register receivers that know
how to create and enqueue ITask from messages posted to some Port. That's it.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
&lt;strong&gt;Recap:&lt;/strong&gt; 
&lt;br&gt;
We post messages to different Port&amp;lt;T&amp;gt; and write receivers that "listen" to the
messages based on some rules (one receiver listen to every message, one listen to
only one message, one listen to X messages etc). When the receiver's rules apply,
the CCR will dequeue all the relevant (applied the rule) messages from the Port&amp;lt;T&amp;gt;
and wrap them with the supplied delegated as ITask. This ITask instance will be enqueued
to the DispatcherQueue until the Dispatcher have a free thread to handle it. The Dispatcher,
according to the &lt;strong&gt;requested scheduling&lt;/strong&gt; (some ITask must run exclusively,
some can run concurrently, as we've seen), will execute those tasks.
&lt;/p&gt;
&lt;p&gt;
&lt;br&gt;
You can download the complete code (with some extra features) here: &lt;a href="http://www.lnbogen.com/content/binary/SpawnEnumerator.txt"&gt;SpawnEnumerator.txt&lt;/a&gt; (12KB)
- you'll need CCR &amp;amp; log4net dll in order to compile it.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://lnbogen.com/aggbug.ashx?id=40072280-5777-4723-b001-51f1b086cd3d" /&gt;</description>
      <comments>http://lnbogen.com/CommentView,guid,40072280-5777-4723-b001-51f1b086cd3d.aspx</comments>
    </item>
    <item>
      <trackback:ping>http://lnbogen.com/Trackback.aspx?guid=8903eaa3-5157-4b14-8669-8b8ff4c11613</trackback:ping>
      <pingback:server>http://lnbogen.com/pingback.aspx</pingback:server>
      <pingback:target>http://lnbogen.com/PermaLink,guid,8903eaa3-5157-4b14-8669-8b8ff4c11613.aspx</pingback:target>
      <dc:creator>Oren Ellenbogen</dc:creator>
      <wfw:comment>http://lnbogen.com/CommentView,guid,8903eaa3-5157-4b14-8669-8b8ff4c11613.aspx</wfw:comment>
      <wfw:commentRss>http://lnbogen.com/SyndicationService.asmx/GetEntryCommentsRss?guid=8903eaa3-5157-4b14-8669-8b8ff4c11613</wfw:commentRss>
      <slash:comments>2</slash:comments>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
[ this is <a href="http://www.lnbogen.com/Part1SpawnEnumeratorDealingWithBillionsOfIndependentItems.aspx">Part
1</a>, <a href="http://www.lnbogen.com/Part2SpawnEnumeratorDealingWithBillionsOfIndependentItems.aspx">Part
2</a>, <a href="http://www.lnbogen.com/Part3SpawnEnumeratorDealingWithBillionsOfIndependentItems.aspx">Part
3</a> ]
</p>
        <p>
          <a href="http://www.lnbogen.com/DeepDiveIntoCCRAndParallelExtensionsKickoff.aspx">I
promised</a> to write more about <a href="http://msdn.microsoft.com/he-il/magazine/cc163556(en-us).aspx">CCR</a> and
how to use it in practice. 
<br />
There is no better way to explain how infrastructure work then writing some code and
play with it, so lets toy with a simple utility, based on CCR under the hood.
</p>
        <p>
          <strong>Scenario</strong>: you've got billions of *<em>independent</em>* tasks you
need to execute as fast as possible. 
<br /><strong>Requirements</strong>:
</p>
        <ol>
          <li>
Amount of "worker threads" should be easy to define. obviously. 
</li>
          <li>
Memory consumption - don't eat more than you can chew. We don't want to hold everything
in memory, this should be easy to configure. 
</li>
          <li>
The process should *<em>not</em>* shutdown due to un-handled exception in one of the
worker threads. 
</li>
          <li>
We want to know when the enumerator is depleted and/or all items were completed. This
is crucial for testing and adjusting parameters.</li>
        </ol>
        <p>
 
</p>
        <p>
The general notion behind SpawnEnumerator is something like this:<br /></p>
        <p>
          <a href="http://www.lnbogen.com/content/binary/SpawnEnumeratordealingwithbillionsofinde_D9EA/SpawnEnumerator_generalIdea.jpg">
            <img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="191" alt="SpawnEnumerator_generalIdea" src="http://www.lnbogen.com/content/binary/SpawnEnumeratordealingwithbillionsofinde_D9EA/SpawnEnumerator_generalIdea_thumb.jpg" width="645" border="0" />
          </a>
        </p>
        <p>
 
</p>
        <p>
We're pulling a bulk of items from the enumerator, each one of them is actually a
"wannabe" item. Combining the value of each T with a given "item handler" could be
transformed into an actual task, waiting for its turn in the "threads pool". Once
the port/queue of "items to execute" reach the lower limit, we'll pull another bulk
of items from the enumerator until the enumerator is depleted.
</p>
        <p>
          <br />
          <strong>API playground</strong>:
</p>
        <p>
SpawnEnumerator&lt;T&gt;.Start(int numberOfThreads, string threadPoolName, int numberOfItemsToHoldInMemory,
IEnumerator&lt;T&gt; enumerator, Action&lt;T&gt; singleItemHandler)
</p>
        <blockquote>
          <p>
T = type of items we would like to run. if we have 10,000,000 items of type int, we'll
supply "int" as T.<br />
numberOfThreads = how many worker threads do we want to run?<br />
threadPoolName = name the worker threads for easier debugging.<br />
numberOfItemsToHoldInMemory = rough number of items we want to hold in memory, to
make sure memory consumption won't blow up in our face.<br />
enumerator = the enumerator of "items" to execute, assuming that it will hold a *<em>huge</em>*
amount of tasks.<br />
singleItemHandler = delegate that receives 1 item and handle it.
</p>
        </blockquote>
        <p>
event Action&lt;DateTime&gt; EnumeratorDepleted
</p>
        <p>
event Action&lt;DateTime&gt; AllTasksAreCompleted
</p>
        <p>
          <br />
          <strong>Test playground:</strong>
        </p>
        <p>
(written in notepad, sorry for stupid mistakes) 
</p>
        <p>
[Test]<br />
public void Execute_LargeEnumeratorOfNumbers_ExecuteAllItems<br />
{
</p>
        <blockquote>
          <p>
// arrange:<br />
int numberOfThreads = 10;<br />
string threadPoolName = "mypool";<br />
int numberOfItemsToHoldInMemory = 100;<br /><br />
IEnumerator&lt;int&gt; items = Yield.For(1, 10000); // yield return numbers from 1-10000<br />
Action&lt;int&gt; singleItemHandler = delegate(int item) {  /* sum the given
number, via Interlocked.Add */ };<br /><br />
ManualResetEvent trigger = new ManualResetEvent(false); 
</p>
        </blockquote>
        <blockquote>
          <p>
// act:<br />
_executor = SpawnEnumerator&lt;int&gt;.Start(threadPoolSize, threadPoolName, numberOfItemsToHoldInMemory,
items, singleItemHandler))<br />
_executor.AllTasksAreCompleted += delegate { trigger.Set(); };    
<br /><br />
// assert:<br />
bool signaled = trigger.WaitOne(TimeSpan.FromSeconds(1), false);<br />
Assert.IsTrue(signaled, "timedout reached, that shouldn't happen!");<br />
// assert that all of the items were called by matching sum of 1-N sequential numbers
(simple formula) to what we collected in the handler
</p>
        </blockquote>
        <p>
}
</p>
        <p>
          <br />
* In the "test teardown" we can check if _executor is not null and if so Dispose it
to close the "worker threads".
</p>
        <p>
          <strong>
          </strong> 
</p>
        <p>
          <strong>Next post - Implementing SpawnEnumerator via CCR.</strong>
        </p>
        <img width="0" height="0" src="http://lnbogen.com/aggbug.ashx?id=8903eaa3-5157-4b14-8669-8b8ff4c11613" />
      </body>
      <title>Part1: SpawnEnumerator, dealing with billions of independent items</title>
      <guid isPermaLink="false">http://lnbogen.com/PermaLink,guid,8903eaa3-5157-4b14-8669-8b8ff4c11613.aspx</guid>
      <link>http://lnbogen.com/2008/10/13/Part1SpawnEnumeratorDealingWithBillionsOfIndependentItems.aspx</link>
      <pubDate>Mon, 13 Oct 2008 14:50:48 GMT</pubDate>
      <description>&lt;p&gt;
[ this is &lt;a href="http://www.lnbogen.com/Part1SpawnEnumeratorDealingWithBillionsOfIndependentItems.aspx"&gt;Part
1&lt;/a&gt;, &lt;a href="http://www.lnbogen.com/Part2SpawnEnumeratorDealingWithBillionsOfIndependentItems.aspx"&gt;Part
2&lt;/a&gt;, &lt;a href="http://www.lnbogen.com/Part3SpawnEnumeratorDealingWithBillionsOfIndependentItems.aspx"&gt;Part
3&lt;/a&gt; ]
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://www.lnbogen.com/DeepDiveIntoCCRAndParallelExtensionsKickoff.aspx"&gt;I
promised&lt;/a&gt; to write more about &lt;a href="http://msdn.microsoft.com/he-il/magazine/cc163556(en-us).aspx"&gt;CCR&lt;/a&gt; and
how to use it in practice. 
&lt;br&gt;
There is no better way to explain how infrastructure work then writing some code and
play with it, so lets toy with a simple utility, based on CCR under the hood.
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;Scenario&lt;/strong&gt;: you've got billions of *&lt;em&gt;independent&lt;/em&gt;* tasks you
need to execute as fast as possible. 
&lt;br&gt;
&lt;strong&gt;Requirements&lt;/strong&gt;:
&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
Amount of "worker threads" should be easy to define. obviously. 
&lt;li&gt;
Memory consumption - don't eat more than you can chew. We don't want to hold everything
in memory, this should be easy to configure. 
&lt;li&gt;
The process should *&lt;em&gt;not&lt;/em&gt;* shutdown due to un-handled exception in one of the
worker threads. 
&lt;li&gt;
We want to know when the enumerator is depleted and/or all items were completed. This
is crucial for testing and adjusting parameters.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p&gt;
The general notion behind SpawnEnumerator is something like this:&lt;br&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://www.lnbogen.com/content/binary/SpawnEnumeratordealingwithbillionsofinde_D9EA/SpawnEnumerator_generalIdea.jpg"&gt;&lt;img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="191" alt="SpawnEnumerator_generalIdea" src="http://www.lnbogen.com/content/binary/SpawnEnumeratordealingwithbillionsofinde_D9EA/SpawnEnumerator_generalIdea_thumb.jpg" width="645" border="0"&gt;&lt;/a&gt; 
&lt;/p&gt;
&lt;p&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p&gt;
We're pulling a bulk of items from the enumerator, each one of them is actually a
"wannabe" item. Combining the value of each T with a given "item handler" could be
transformed into an actual task, waiting for its turn in the "threads pool". Once
the port/queue of "items to execute" reach the lower limit, we'll pull another bulk
of items from the enumerator until the enumerator is depleted.
&lt;/p&gt;
&lt;p&gt;
&lt;br&gt;
&lt;strong&gt;API playground&lt;/strong&gt;:
&lt;/p&gt;
&lt;p&gt;
SpawnEnumerator&amp;lt;T&amp;gt;.Start(int numberOfThreads, string threadPoolName, int numberOfItemsToHoldInMemory,
IEnumerator&amp;lt;T&amp;gt; enumerator, Action&amp;lt;T&amp;gt; singleItemHandler)
&lt;/p&gt;
&lt;blockquote&gt; 
&lt;p&gt;
T = type of items we would like to run. if we have 10,000,000 items of type int, we'll
supply "int" as T.&lt;br&gt;
numberOfThreads = how many worker threads do we want to run?&lt;br&gt;
threadPoolName = name the worker threads for easier debugging.&lt;br&gt;
numberOfItemsToHoldInMemory = rough number of items we want to hold in memory, to
make sure memory consumption won't blow up in our face.&lt;br&gt;
enumerator = the enumerator of "items" to execute, assuming that it will hold a *&lt;em&gt;huge&lt;/em&gt;*
amount of tasks.&lt;br&gt;
singleItemHandler = delegate that receives 1 item and handle it.
&lt;/p&gt;
&lt;/blockquote&gt; 
&lt;p&gt;
event Action&amp;lt;DateTime&amp;gt; EnumeratorDepleted
&lt;/p&gt;
&lt;p&gt;
event Action&amp;lt;DateTime&amp;gt; AllTasksAreCompleted
&lt;/p&gt;
&lt;p&gt;
&lt;br&gt;
&lt;strong&gt;Test playground:&lt;/strong&gt;
&lt;/p&gt;
&lt;p&gt;
(written in notepad, sorry for stupid mistakes) 
&lt;p&gt;
[Test]&lt;br&gt;
public void Execute_LargeEnumeratorOfNumbers_ExecuteAllItems&lt;br&gt;
{
&lt;/p&gt;
&lt;blockquote&gt; 
&lt;p&gt;
// arrange:&lt;br&gt;
int numberOfThreads = 10;&lt;br&gt;
string threadPoolName = "mypool";&lt;br&gt;
int numberOfItemsToHoldInMemory = 100;&lt;br&gt;
&lt;br&gt;
IEnumerator&amp;lt;int&amp;gt; items = Yield.For(1, 10000); // yield return numbers from 1-10000&lt;br&gt;
Action&amp;lt;int&amp;gt; singleItemHandler = delegate(int item) {&amp;nbsp; /* sum the given
number, via Interlocked.Add */ };&lt;br&gt;
&lt;br&gt;
ManualResetEvent trigger = new ManualResetEvent(false); 
&lt;/p&gt;
&lt;/blockquote&gt; &lt;blockquote&gt; 
&lt;p&gt;
// act:&lt;br&gt;
_executor = SpawnEnumerator&amp;lt;int&amp;gt;.Start(threadPoolSize, threadPoolName, numberOfItemsToHoldInMemory,
items, singleItemHandler))&lt;br&gt;
_executor.AllTasksAreCompleted += delegate { trigger.Set(); };&amp;nbsp;&amp;nbsp;&amp;nbsp; 
&lt;br&gt;
&lt;br&gt;
// assert:&lt;br&gt;
bool signaled = trigger.WaitOne(TimeSpan.FromSeconds(1), false);&lt;br&gt;
Assert.IsTrue(signaled, "timedout reached, that shouldn't happen!");&lt;br&gt;
// assert that all of the items were called by matching sum of 1-N sequential numbers
(simple formula) to what we collected in the handler
&lt;/p&gt;
&lt;/blockquote&gt; 
&lt;p&gt;
}
&lt;/p&gt;
&lt;p&gt;
&lt;br&gt;
* In the "test teardown" we can check if _executor is not null and if so Dispose it
to close the "worker threads".
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;&lt;/strong&gt;&amp;nbsp;
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;Next post - Implementing SpawnEnumerator via CCR.&lt;/strong&gt;
&lt;/p&gt;
&lt;img width="0" height="0" src="http://lnbogen.com/aggbug.ashx?id=8903eaa3-5157-4b14-8669-8b8ff4c11613" /&gt;</description>
      <comments>http://lnbogen.com/CommentView,guid,8903eaa3-5157-4b14-8669-8b8ff4c11613.aspx</comments>
    </item>
    <item>
      <trackback:ping>http://lnbogen.com/Trackback.aspx?guid=0c0d13fe-e0b9-4f15-8e10-dceacdc6e44f</trackback:ping>
      <pingback:server>http://lnbogen.com/pingback.aspx</pingback:server>
      <pingback:target>http://lnbogen.com/PermaLink,guid,0c0d13fe-e0b9-4f15-8e10-dceacdc6e44f.aspx</pingback:target>
      <dc:creator>Oren Ellenbogen</dc:creator>
      <wfw:comment>http://lnbogen.com/CommentView,guid,0c0d13fe-e0b9-4f15-8e10-dceacdc6e44f.aspx</wfw:comment>
      <wfw:commentRss>http://lnbogen.com/SyndicationService.asmx/GetEntryCommentsRss?guid=0c0d13fe-e0b9-4f15-8e10-dceacdc6e44f</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
This is mostly a self-note but heck, maybe someone will reach this post via <a href="http://www.delver.com">Delver</a> (or <a href="http://www.google.com">Google</a> :)),
so I'm all about sharing.
</p>
        <p>
Anyway, we're using (for now) Bugzilla and I tried to get all the "open" bugs for
my team with status equal to X,Y,Z. 
</p>
        <p>
Sounds easy right? well, you are ... sadly mistaken.<br />
After investing 15 minutes banging my head into the nearest wall with “Bugzilla Advanced
Serach” (well, I'll be polite and say it's "advanced" alright), I gave in on that
one.<br />
Instead, I hacked the url a bit to understand the dark voodoo of Bugzilla and voila,
2 minutes later: 
</p>
        <p>
          <a href="http://qabugz/cgi-bin/bugzilla/buglist.cgi">http://qabugz/cgi-bin/bugzilla/buglist.cgi</a>
          <br />
?bug_status=NEW<br />
&amp;bug_status=ASSIGNED<br />
&amp;bug_status=REOPENED<br />
&amp;assigned_to=Joe<br />
&amp;assigned_to=Joe2<br />
&amp;assigned_to=Joe3<br />
&amp;query_format=specific<br />
&amp;field0-0-0=bug_status<br />
&amp;field0-0-1=assigned_to<br />
&amp;type0-0-0=anyexact<br />
&amp;type0-0-1=anyexact<br />
&amp;order=bugs.bug_severity 
</p>
        <p>
          <br />
Just remove the “break line” of course (this is easier to edit) and replace "Joe"
with your favorite developer name.<br /><br />
If you want to make it a bit more complex, here is a nice site with the supported
field names:<br /><a title="http://pkp.sfu.ca/bugzilla/page.cgi?id=quicksearchhack.html" href="http://pkp.sfu.ca/bugzilla/page.cgi?id=quicksearchhack.html">http://pkp.sfu.ca/bugzilla/page.cgi?id=quicksearchhack.html</a></p>
        <p>
 
</p>
        <p>
Anyway, I hope it will help someone.
</p>
        <p>
* geeky btw – notice the funny “binary index” of the fields! made me laugh quite a
bit, being the geek that I am.
</p>
        <img width="0" height="0" src="http://lnbogen.com/aggbug.ashx?id=0c0d13fe-e0b9-4f15-8e10-dceacdc6e44f" />
      </body>
      <title>Building search queries in Bugzilla</title>
      <guid isPermaLink="false">http://lnbogen.com/PermaLink,guid,0c0d13fe-e0b9-4f15-8e10-dceacdc6e44f.aspx</guid>
      <link>http://lnbogen.com/2008/10/06/BuildingSearchQueriesInBugzilla.aspx</link>
      <pubDate>Mon, 06 Oct 2008 13:20:44 GMT</pubDate>
      <description>&lt;p&gt;
This is mostly a self-note but heck, maybe someone will reach this post via &lt;a href="http://www.delver.com"&gt;Delver&lt;/a&gt; (or &lt;a href="http://www.google.com"&gt;Google&lt;/a&gt; :)),
so I'm all about sharing.
&lt;/p&gt;
&lt;p&gt;
Anyway, we're using (for now) Bugzilla and I tried to get all the "open" bugs for
my team with status equal to X,Y,Z. 
&lt;/p&gt;
&lt;p&gt;
Sounds easy right? well, you are ... sadly mistaken.&lt;br&gt;
After investing 15 minutes banging my head into the nearest wall with “Bugzilla Advanced
Serach” (well, I'll be polite and say it's "advanced" alright), I gave in on that
one.&lt;br&gt;
Instead, I hacked the url a bit to understand the dark voodoo of Bugzilla and voila,
2 minutes later: 
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://qabugz/cgi-bin/bugzilla/buglist.cgi"&gt;http://qabugz/cgi-bin/bugzilla/buglist.cgi&lt;/a&gt;
&lt;br&gt;
?bug_status=NEW&lt;br&gt;
&amp;amp;bug_status=ASSIGNED&lt;br&gt;
&amp;amp;bug_status=REOPENED&lt;br&gt;
&amp;amp;assigned_to=Joe&lt;br&gt;
&amp;amp;assigned_to=Joe2&lt;br&gt;
&amp;amp;assigned_to=Joe3&lt;br&gt;
&amp;amp;query_format=specific&lt;br&gt;
&amp;amp;field0-0-0=bug_status&lt;br&gt;
&amp;amp;field0-0-1=assigned_to&lt;br&gt;
&amp;amp;type0-0-0=anyexact&lt;br&gt;
&amp;amp;type0-0-1=anyexact&lt;br&gt;
&amp;amp;order=bugs.bug_severity 
&lt;/p&gt;
&lt;p&gt;
&lt;br&gt;
Just remove the “break line” of course (this is easier to edit) and replace "Joe"
with your favorite developer name.&lt;br&gt;
&lt;br&gt;
If you want to make it a bit more complex, here is a nice site with the supported
field names:&lt;br&gt;
&lt;a title="http://pkp.sfu.ca/bugzilla/page.cgi?id=quicksearchhack.html" href="http://pkp.sfu.ca/bugzilla/page.cgi?id=quicksearchhack.html"&gt;http://pkp.sfu.ca/bugzilla/page.cgi?id=quicksearchhack.html&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p&gt;
Anyway, I hope it will help someone.
&lt;/p&gt;
&lt;p&gt;
* geeky btw – notice the funny “binary index” of the fields! made me laugh quite a
bit, being the geek that I am.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://lnbogen.com/aggbug.ashx?id=0c0d13fe-e0b9-4f15-8e10-dceacdc6e44f" /&gt;</description>
      <comments>http://lnbogen.com/CommentView,guid,0c0d13fe-e0b9-4f15-8e10-dceacdc6e44f.aspx</comments>
    </item>
    <item>
      <trackback:ping>http://lnbogen.com/Trackback.aspx?guid=fc9e9585-5f5e-423c-8676-524a5de0cefa</trackback:ping>
      <pingback:server>http://lnbogen.com/pingback.aspx</pingback:server>
      <pingback:target>http://lnbogen.com/PermaLink,guid,fc9e9585-5f5e-423c-8676-524a5de0cefa.aspx</pingback:target>
      <dc:creator>Oren Ellenbogen</dc:creator>
      <wfw:comment>http://lnbogen.com/CommentView,guid,fc9e9585-5f5e-423c-8676-524a5de0cefa.aspx</wfw:comment>
      <wfw:commentRss>http://lnbogen.com/SyndicationService.asmx/GetEntryCommentsRss?guid=fc9e9585-5f5e-423c-8676-524a5de0cefa</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
One of the biggest challenges in management is be able to track your own rhythm, making
sure your plans are executed and things go smoothly. 
</p>
        <p>
In my previous post about <a href="http://www.lnbogen.com/DrivenBySelfOrganization.aspx">Driven
By Self Organization</a> I stressed the importance of making things visible and plan
for the future. How can one set the environment of the team to drive the entire team
to success? 
</p>
        <p>
Thinking about it lately made me think that I have my own thoughts about what should
be visible, how the team should react internally and how should one behave in such
team as a Team Lead. Don't get me wrong, I don't have 30 years of experience leading
small&lt;-&gt;giant teams for small&lt;-&gt;giant companies, these ideas are solely
based on my gut feelings: making things SIMPLE (KISS) so the entire team will be driven
by self-organization without the "burden" of self-management. If things are easy to
do, it's easier to get better at them. 
</p>
        <p>
The trick is to <strong>allow all of the members</strong> in the team to be part of
the organize-&gt;execute game. Some will play, some won't, but they will all be affected
by the always-ready environment and notice how inner-interaction change their day.
By making it visible, they will be motivated to take action (it will feel natural).
I came up with this drawing to expose our <strong>sprint</strong> plans and progress: 
</p>
        <p>
  
</p>
        <p>
 <a href="http://www.lnbogen.com/content/binary/SelfOrganizationforDevelopmentTeams_F65E/image.png"><img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="437" alt="image" src="http://www.lnbogen.com/content/binary/SelfOrganizationforDevelopmentTeams_F65E/image_thumb.png" width="738" border="0" /></a></p>
        <p>
  
</p>
        <p>
This is a very SIMPLE presentation of the current sprint features and every-day progress
- "cards" will move between columns as people work on them.<br />
There are some magic "self organization" tricks integrated into this 1-Visible-view: 
</p>
        <ol>
          <li>
Achievement-based planning: Before arranging the features/cards, we try to set the
"deliveries" for the week. This is a free-text (don't be tempted to make it a list
of features) ideas to "set the mood" for the week. It will describe features we want
to finish, some design we need to handle before the next week, some quality check
we want to pass ("make sure no critical/major bugs are open") etc. They help to plan
the week as they define goals that are measurable, driving the team to achievement-based
planning rather than like-best-do-first development. 
</li>
          <li>
Visibility is key: Every member of the team knows exactly what's left for the <strong>entire</strong> team
on a weekly level. No more "but I finished all my tasks two days earlier than we've
talked! what can I do that Joe is new here and couldn't continue as you thought? oh,
I didn't know we are dependent on his task before we can release the package..." 
</li>
          <li>
Help each other: remind yourselves that things need to be completed, help one another
by helping out when someone is behind of schedule (alright Joe, I'll take Feature
A, don't worry). The board will make it easier to know "where can I help?" 
</li>
          <li>
We want Quality: Nothing is DONE until it's tested and fixed. The idea of splitting
"coded" tasks from "tested" tasks is to set the mood for "production ready" code. 
</li>
          <li>
Small goals are easier to achieve: Splitting the sprint into smaller chunks make it
easier to win small battles. Each week defines small trophies - the "deliveries" we
promised for that week. 
</li>
          <li>
Plan leftovers for tomorrow: at the end of every week\sprint, you could easily see
what was left. Discuss why it failed and plan it for <strong>tomorrow </strong>(=next
week or next sprint). 
</li>
        </ol>
        <p>
 
</p>
        <p>
Team Lead in such a team will mostly act as a coach, helping the team members to split
the features into tasks, remove obstacles, motivate cooperation and taking notes about
"how can we get better?". Most importantly, it will allow her (or him) to be productive
and feel he can help the team's effort instead of the constant-chaos feeling managers
tend to have when things go poorly. The team members are aware of the plans and can
balance the efforts to break loose of this chaos-like feeling.
</p>
        <img width="0" height="0" src="http://lnbogen.com/aggbug.ashx?id=fc9e9585-5f5e-423c-8676-524a5de0cefa" />
      </body>
      <title>Self Organization inside a Team</title>
      <guid isPermaLink="false">http://lnbogen.com/PermaLink,guid,fc9e9585-5f5e-423c-8676-524a5de0cefa.aspx</guid>
      <link>http://lnbogen.com/2008/09/30/SelfOrganizationInsideATeam.aspx</link>
      <pubDate>Tue, 30 Sep 2008 16:07:31 GMT</pubDate>
      <description>&lt;p&gt;
One of the biggest challenges in management is be able to track your own rhythm, making
sure your plans are executed and things go smoothly. 
&lt;p&gt;
In my previous post about &lt;a href="http://www.lnbogen.com/DrivenBySelfOrganization.aspx"&gt;Driven
By Self Organization&lt;/a&gt; I stressed the importance of making things visible and plan
for the future. How can one set the environment of the team to drive the entire team
to success? 
&lt;p&gt;
Thinking about it lately made me think that I have my own thoughts about what should
be visible, how the team should react internally and how should one behave in such
team as a Team Lead. Don't get me wrong, I don't have 30 years of experience leading
small&amp;lt;-&amp;gt;giant teams for small&amp;lt;-&amp;gt;giant companies, these ideas are solely
based on my gut feelings: making things SIMPLE (KISS) so the entire team will be driven
by self-organization without the "burden" of self-management. If things are easy to
do, it's easier to get better at them. 
&lt;p&gt;
The trick is to &lt;strong&gt;allow all of the members&lt;/strong&gt; in the team to be part of
the organize-&amp;gt;execute game. Some will play, some won't, but they will all be affected
by the always-ready environment and notice how inner-interaction change their day.
By making it visible, they will be motivated to take action (it will feel natural).
I came up with this drawing to expose our &lt;strong&gt;sprint&lt;/strong&gt; plans and progress: 
&lt;p&gt;
&amp;nbsp; 
&lt;p&gt;
&amp;nbsp;&lt;a href="http://www.lnbogen.com/content/binary/SelfOrganizationforDevelopmentTeams_F65E/image.png"&gt;&lt;img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="437" alt="image" src="http://www.lnbogen.com/content/binary/SelfOrganizationforDevelopmentTeams_F65E/image_thumb.png" width="738" border="0"&gt;&lt;/a&gt; 
&lt;p&gt;
&amp;nbsp; 
&lt;p&gt;
This is a very SIMPLE presentation of the current sprint features and every-day progress
- "cards" will move between columns as people work on them.&lt;br&gt;
There are some magic "self organization" tricks integrated into this 1-Visible-view: 
&lt;ol&gt;
&lt;li&gt;
Achievement-based planning: Before arranging the features/cards, we try to set the
"deliveries" for the week. This is a free-text (don't be tempted to make it a list
of features) ideas to "set the mood" for the week. It will describe features we want
to finish, some design we need to handle before the next week, some quality check
we want to pass ("make sure no critical/major bugs are open") etc. They help to plan
the week as they define goals that are measurable, driving the team to achievement-based
planning rather than like-best-do-first development. 
&lt;li&gt;
Visibility is key: Every member of the team knows exactly what's left for the &lt;strong&gt;entire&lt;/strong&gt; team
on a weekly level. No more "but I finished all my tasks two days earlier than we've
talked! what can I do that Joe is new here and couldn't continue as you thought? oh,
I didn't know we are dependent on his task before we can release the package..." 
&lt;li&gt;
Help each other: remind yourselves that things need to be completed, help one another
by helping out when someone is behind of schedule (alright Joe, I'll take Feature
A, don't worry). The board will make it easier to know "where can I help?" 
&lt;li&gt;
We want Quality: Nothing is DONE until it's tested and fixed. The idea of splitting
"coded" tasks from "tested" tasks is to set the mood for "production ready" code. 
&lt;li&gt;
Small goals are easier to achieve: Splitting the sprint into smaller chunks make it
easier to win small battles. Each week defines small trophies - the "deliveries" we
promised for that week. 
&lt;li&gt;
Plan leftovers for tomorrow: at the end of every week\sprint, you could easily see
what was left. Discuss why it failed and plan it for &lt;strong&gt;tomorrow &lt;/strong&gt;(=next
week or next sprint). 
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p&gt;
Team Lead in such a team will mostly act as a coach, helping the team members to split
the features into tasks, remove obstacles, motivate cooperation and taking notes about
"how can we get better?". Most importantly, it will allow her (or him) to be productive
and feel he can help the team's effort instead of the constant-chaos feeling managers
tend to have when things go poorly. The team members are aware of the plans and can
balance the efforts to break loose of this chaos-like feeling.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://lnbogen.com/aggbug.ashx?id=fc9e9585-5f5e-423c-8676-524a5de0cefa" /&gt;</description>
      <comments>http://lnbogen.com/CommentView,guid,fc9e9585-5f5e-423c-8676-524a5de0cefa.aspx</comments>
    </item>
    <item>
      <trackback:ping>http://lnbogen.com/Trackback.aspx?guid=c5f0ef03-0a94-44b2-ada3-0b09c43f5a97</trackback:ping>
      <pingback:server>http://lnbogen.com/pingback.aspx</pingback:server>
      <pingback:target>http://lnbogen.com/PermaLink,guid,c5f0ef03-0a94-44b2-ada3-0b09c43f5a97.aspx</pingback:target>
      <dc:creator>Oren Ellenbogen</dc:creator>
      <wfw:comment>http://lnbogen.com/CommentView,guid,c5f0ef03-0a94-44b2-ada3-0b09c43f5a97.aspx</wfw:comment>
      <wfw:commentRss>http://lnbogen.com/SyndicationService.asmx/GetEntryCommentsRss?guid=c5f0ef03-0a94-44b2-ada3-0b09c43f5a97</wfw:commentRss>
      <slash:comments>1</slash:comments>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
Think about a young fellow, wanting to get into shape. Here are 2 scenarios of how
one can tackle that wish:
</p>
        <p>
          <strong>1.</strong> Create a plan and "manage yourself" to keep it. 
</p>
        <p>
   20:00 - set the clock to 06:00<br />
   06:00 - wake up, <strong>make sure</strong> you're not falling back to
sleep! get dressed etc<br />
   06:15 - <strong>make sure</strong> to eat something small and drink some
water<br />
   06:35 - run 5km<br />
   08:00 - <strong>make sure</strong> your bag is ready for school<br />
   08:15 - go to school<br />
   ... 
<br />
   20:00 - set the clock to 06:00
</p>
        <p>
          <strong>
            <br />
2.</strong> Organize things to drive your day:
</p>
        <p>
   20:00 - put your shoes next to your bed, set your clock to 06:00 and
set it FAR from the bed, prepare a little something to eat for tomorrow morning, prepare
your bag for (tomorrow's) school.<br />
   06:00 - wake up - go close the damn clock (you need to stand in order
to do it), get dressed etc.<br />
   06:15 - eat something small and drink some water<br />
   06:35 - run 5km<br />
   08:00 - relax for a few minutes and then go to school<br />
   ... 
<br />
   20:00 - put your shoes next to your bed, set your clock to 06:00 and
set it FAR from the bed, prepare a little something to eat for tomorrow morning, prepare
your bag for (tomorrow's) school.
</p>
        <p>
          <br />
          <strong>Where most of us fail?</strong>
        </p>
        <p>
I might be wrong, but it seems that a lot of us (myself included) simply can't manage
our time wisely during the day, <strong>for long period of time</strong>. It's too
easy to forget something to do TODAY when you had to force yourself to plan it TODAY.
It's too easy to fail. It's too easy to stop the rhythm. 
<br /><br />
This is why most of us can't lose weight, can't get into shape, can't read 5 books
every month etc. 
</p>
        <p>
          <strong>
            <br />
Driven by Self-organization</strong>
        </p>
        <p>
To me, it means that I want to set <strong>my environment</strong> to drive me into
success. If I'll take the time to prepare my tomorrow, little chance I'll fail due
to laziness: (1) I'm planning for TOMORROW, so what do I care to invest the time?
I only plan things and set the environment / mood. I don't need to run the 5km now,
I only want to make sure it will be easier to achieve tomorrow and (2) tomorrow morning,
surprise surprise, everything is ready for me! I don't need to wake up and find out
that I forgot a stupid thing like the fact that my shoes are in the washing machine.
The rules are pretty easy: de-couple planning from performing and make sure everything
you need for those actions are visible and available for the time you'll need them.
</p>
        <p>
          <br />
Although it seems like planning is more tedious than actually doing the task, planning
for the <strong>future</strong> is quite relaxing. Try it: plan your tomorrow at the
end of today, think about what should be set so your tomorrow will go smoothly. It
will make it easier for you to come in the morning and simply perform, without the
burden of planning fast to perform now:
</p>
        <p>
"hhmmm... alright, it's Wednesday, what should I do today... gosh, so many things
to complete! Maybe I'll start with sending those emails... naaa.. don't have power
for that now.. maybe I'll finish that task I promised yesterday! naa.. she don't need
it for today anyway... crap! I don't have the energy to deal with it! alright, first
thing is to grab a cup of coffee".
</p>
        <p>
This leads to "do what I like best first" syndrome.
</p>
        <p>
          <br />
At the end of the day, before going home, go over the things you've accomplished and
try to see what is left for tomorrow. Relax, you don't need to do those chores now.
Write everything you should accomplish for tomorrow down (with time estimations) and
go home smiling, knowing that your tomorrow is best planned for achievements rather
than for your personal whims. 
</p>
        <img width="0" height="0" src="http://lnbogen.com/aggbug.ashx?id=c5f0ef03-0a94-44b2-ada3-0b09c43f5a97" />
      </body>
      <title>Driven by Self Organization</title>
      <guid isPermaLink="false">http://lnbogen.com/PermaLink,guid,c5f0ef03-0a94-44b2-ada3-0b09c43f5a97.aspx</guid>
      <link>http://lnbogen.com/2008/09/30/DrivenBySelfOrganization.aspx</link>
      <pubDate>Tue, 30 Sep 2008 15:12:18 GMT</pubDate>
      <description>&lt;p&gt;
Think about a young fellow, wanting to get into shape. Here are 2 scenarios of how
one can tackle that wish:
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;1.&lt;/strong&gt; Create a plan and "manage yourself" to keep it. 
&lt;/p&gt;
&lt;p&gt;
&amp;nbsp;&amp;nbsp; 20:00 - set the clock to 06:00&lt;br&gt;
&amp;nbsp;&amp;nbsp; 06:00 - wake up, &lt;strong&gt;make sure&lt;/strong&gt; you're not falling back to
sleep! get dressed etc&lt;br&gt;
&amp;nbsp;&amp;nbsp; 06:15 - &lt;strong&gt;make sure&lt;/strong&gt; to eat something small and drink some
water&lt;br&gt;
&amp;nbsp;&amp;nbsp; 06:35 - run 5km&lt;br&gt;
&amp;nbsp;&amp;nbsp; 08:00 - &lt;strong&gt;make sure&lt;/strong&gt; your bag is ready for school&lt;br&gt;
&amp;nbsp;&amp;nbsp; 08:15 - go to school&lt;br&gt;
&amp;nbsp;&amp;nbsp; ... 
&lt;br&gt;
&amp;nbsp;&amp;nbsp; 20:00 - set the clock to 06:00
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;
&lt;br&gt;
2.&lt;/strong&gt; Organize things to drive your day:
&lt;/p&gt;
&lt;p&gt;
&amp;nbsp;&amp;nbsp; 20:00 - put your shoes next to your bed, set your clock to 06:00 and
set it FAR from the bed, prepare a little something to eat for tomorrow morning, prepare
your bag for (tomorrow's) school.&lt;br&gt;
&amp;nbsp;&amp;nbsp; 06:00 - wake up - go close the damn clock (you need to stand in order
to do it), get dressed etc.&lt;br&gt;
&amp;nbsp;&amp;nbsp; 06:15 - eat something small and drink some water&lt;br&gt;
&amp;nbsp;&amp;nbsp; 06:35 - run 5km&lt;br&gt;
&amp;nbsp;&amp;nbsp; 08:00 - relax for a few minutes and then go to school&lt;br&gt;
&amp;nbsp;&amp;nbsp; ... 
&lt;br&gt;
&amp;nbsp;&amp;nbsp; 20:00 - put your shoes next to your bed, set your clock to 06:00 and
set it FAR from the bed, prepare a little something to eat for tomorrow morning, prepare
your bag for (tomorrow's) school.
&lt;/p&gt;
&lt;p&gt;
&lt;br&gt;
&lt;strong&gt;Where most of us fail?&lt;/strong&gt;
&lt;/p&gt;
&lt;p&gt;
I might be wrong, but it seems that a lot of us (myself included) simply can't manage
our time wisely during the day, &lt;strong&gt;for long period of time&lt;/strong&gt;. It's too
easy to forget something to do TODAY when you had to force yourself to plan it TODAY.
It's too easy to fail. It's too easy to stop the rhythm. 
&lt;br&gt;
&lt;br&gt;
This is why most of us can't lose weight, can't get into shape, can't read 5 books
every month etc. 
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;
&lt;br&gt;
Driven by Self-organization&lt;/strong&gt;
&lt;/p&gt;
&lt;p&gt;
To me, it means that I want to set &lt;strong&gt;my environment&lt;/strong&gt; to drive me into
success. If I'll take the time to prepare my tomorrow, little chance I'll fail due
to laziness: (1) I'm planning for TOMORROW, so what do I care to invest the time?
I only plan things and set the environment / mood. I don't need to run the 5km now,
I only want to make sure it will be easier to achieve tomorrow and (2) tomorrow morning,
surprise surprise, everything is ready for me! I don't need to wake up and find out
that I forgot a stupid thing like the fact that my shoes are in the washing machine.
The rules are pretty easy: de-couple planning from performing and make sure everything
you need for those actions are visible and available for the time you'll need them.
&lt;/p&gt;
&lt;p&gt;
&lt;br&gt;
Although it seems like planning is more tedious than actually doing the task, planning
for the &lt;strong&gt;future&lt;/strong&gt; is quite relaxing. Try it: plan your tomorrow at the
end of today, think about what should be set so your tomorrow will go smoothly. It
will make it easier for you to come in the morning and simply perform, without the
burden of planning fast to perform now:
&lt;/p&gt;
&lt;p&gt;
"hhmmm... alright, it's Wednesday, what should I do today... gosh, so many things
to complete! Maybe I'll start with sending those emails... naaa.. don't have power
for that now.. maybe I'll finish that task I promised yesterday! naa.. she don't need
it for today anyway... crap! I don't have the energy to deal with it! alright, first
thing is to grab a cup of coffee".
&lt;/p&gt;
&lt;p&gt;
This leads to "do what I like best first" syndrome.
&lt;/p&gt;
&lt;p&gt;
&lt;br&gt;
At the end of the day, before going home, go over the things you've accomplished and
try to see what is left for tomorrow. Relax, you don't need to do those chores now.
Write everything you should accomplish for tomorrow down (with time estimations) and
go home smiling, knowing that your tomorrow is best planned for achievements rather
than for your personal whims. 
&lt;/p&gt;
&lt;img width="0" height="0" src="http://lnbogen.com/aggbug.ashx?id=c5f0ef03-0a94-44b2-ada3-0b09c43f5a97" /&gt;</description>
      <comments>http://lnbogen.com/CommentView,guid,c5f0ef03-0a94-44b2-ada3-0b09c43f5a97.aspx</comments>
    </item>
    <item>
      <trackback:ping>http://lnbogen.com/Trackback.aspx?guid=b60e51a0-8158-4292-9aa1-b7a4e3ed2a94</trackback:ping>
      <pingback:server>http://lnbogen.com/pingback.aspx</pingback:server>
      <pingback:target>http://lnbogen.com/PermaLink,guid,b60e51a0-8158-4292-9aa1-b7a4e3ed2a94.aspx</pingback:target>
      <dc:creator>Oren Ellenbogen</dc:creator>
      <wfw:comment>http://lnbogen.com/CommentView,guid,b60e51a0-8158-4292-9aa1-b7a4e3ed2a94.aspx</wfw:comment>
      <wfw:commentRss>http://lnbogen.com/SyndicationService.asmx/GetEntryCommentsRss?guid=b60e51a0-8158-4292-9aa1-b7a4e3ed2a94</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
I'm preparing a set of articles regarding Microsoft CCR and Parallel Extensions, trying
to explain the multi threading libraries supplied by MS and how they are going to
change our life in the multi-core world.
</p>
        <p>
I thought about starting with some architecture point of view for each library, going
over the data structures and then demonstrate usage for real life scenarios. I'll
start with level 100 articles and dive deeper until complex scenarios and how to harness
the framework's full power to your needs.
</p>
        <p>
We had the pleasure here at Delver working with CCR so I'll share with you some of
the code base we created on top of it, some tips for using it correctly and my take
about using these libraries in mainstream applications. 
</p>
        <p>
 
</p>
        <p>
Some nice articles to get you started if you didn't hear about these libraries so
far:
</p>
        <p>
          <a href="http://blogs.msdn.com/pfxteam/archive/2008/08/12/8849984.aspx">Parallel Programming
with .NET : Most Common Performance Issues in Parallel Programs</a>
        </p>
        <p>
          <a href="http://msdn.microsoft.com/msdnmag/issues/06/09/ConcurrentAffairs/default.aspx?loc=&amp;fig=true#fig8">Concurrent
Affairs: Concurrency and Coordination Runtime -- MSDN Magazine, September 2006</a>
        </p>
        <p>
          <a href="http://channel9.msdn.com/wiki/default.aspx/Channel9.ConcurrencyRuntime">Channel9
Wiki: Concurrency Runtime</a>
        </p>
        <p>
          <a href="http://blogs.msdn.com/pfxteam/archive/2008/06/18/8620615.aspx">Parallel Programming
with .NET : Coordination Data Structures Overview</a>
        </p>
        <p>
          <a href="http://blogs.msdn.com/pfxteam/archive/2008/06/21/8629821.aspx">Parallel Programming
with .NET : Fork/Join parallelism with .NET CountdownEvent</a>
        </p>
        <p>
          <a href="http://blogs.msdn.com/pfxteam/archive/2008/03/16/8272833.aspx">Parallel Programming
with .NET : Wrapping an APM implementation with Future&lt;T&gt;</a>
        </p>
        <p>
 
</p>
        <p>
Is there anything specific you're interested to read about regarding those topics
?
</p>
        <img width="0" height="0" src="http://lnbogen.com/aggbug.ashx?id=b60e51a0-8158-4292-9aa1-b7a4e3ed2a94" />
      </body>
      <title>Deep dive into CCR and Parallel Extensions: kick-off</title>
      <guid isPermaLink="false">http://lnbogen.com/PermaLink,guid,b60e51a0-8158-4292-9aa1-b7a4e3ed2a94.aspx</guid>
      <link>http://lnbogen.com/2008/09/16/DeepDiveIntoCCRAndParallelExtensionsKickoff.aspx</link>
      <pubDate>Tue, 16 Sep 2008 12:58:39 GMT</pubDate>
      <description>&lt;p&gt;
I'm preparing a set of articles regarding Microsoft CCR and Parallel Extensions, trying
to explain the multi threading libraries supplied by MS and how they are going to
change our life in the multi-core world.
&lt;/p&gt;
&lt;p&gt;
I thought about starting with some architecture point of view for each library, going
over the data structures and then demonstrate usage for real life scenarios. I'll
start with level 100 articles and dive deeper until complex scenarios and how to harness
the framework's full power to your needs.
&lt;/p&gt;
&lt;p&gt;
We had the pleasure here at Delver working with CCR so I'll share with you some of
the code base we created on top of it, some tips for using it correctly and my take
about using these libraries in mainstream applications. 
&lt;/p&gt;
&lt;p&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p&gt;
Some nice articles to get you started if you didn't hear about these libraries so
far:
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://blogs.msdn.com/pfxteam/archive/2008/08/12/8849984.aspx"&gt;Parallel Programming
with .NET : Most Common Performance Issues in Parallel Programs&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://msdn.microsoft.com/msdnmag/issues/06/09/ConcurrentAffairs/default.aspx?loc=&amp;amp;fig=true#fig8"&gt;Concurrent
Affairs: Concurrency and Coordination Runtime -- MSDN Magazine, September 2006&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://channel9.msdn.com/wiki/default.aspx/Channel9.ConcurrencyRuntime"&gt;Channel9
Wiki: Concurrency Runtime&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://blogs.msdn.com/pfxteam/archive/2008/06/18/8620615.aspx"&gt;Parallel Programming
with .NET : Coordination Data Structures Overview&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://blogs.msdn.com/pfxteam/archive/2008/06/21/8629821.aspx"&gt;Parallel Programming
with .NET : Fork/Join parallelism with .NET CountdownEvent&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://blogs.msdn.com/pfxteam/archive/2008/03/16/8272833.aspx"&gt;Parallel Programming
with .NET : Wrapping an APM implementation with Future&amp;lt;T&amp;gt;&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p&gt;
Is there anything specific you're interested to read about regarding those topics
?
&lt;/p&gt;
&lt;img width="0" height="0" src="http://lnbogen.com/aggbug.ashx?id=b60e51a0-8158-4292-9aa1-b7a4e3ed2a94" /&gt;</description>
      <comments>http://lnbogen.com/CommentView,guid,b60e51a0-8158-4292-9aa1-b7a4e3ed2a94.aspx</comments>
    </item>
    <item>
      <trackback:ping>http://lnbogen.com/Trackback.aspx?guid=b23f5c68-90b9-41a0-b18b-9069bea82c77</trackback:ping>
      <pingback:server>http://lnbogen.com/pingback.aspx</pingback:server>
      <pingback:target>http://lnbogen.com/PermaLink,guid,b23f5c68-90b9-41a0-b18b-9069bea82c77.aspx</pingback:target>
      <dc:creator>Oren Ellenbogen</dc:creator>
      <wfw:comment>http://lnbogen.com/CommentView,guid,b23f5c68-90b9-41a0-b18b-9069bea82c77.aspx</wfw:comment>
      <wfw:commentRss>http://lnbogen.com/SyndicationService.asmx/GetEntryCommentsRss?guid=b23f5c68-90b9-41a0-b18b-9069bea82c77</wfw:commentRss>
      <slash:comments>2</slash:comments>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
Having to parallelize almost every bit of code here at Delver, some common patterns
emerged while we wrote a lot of back-end code.<br />
I remember reading about a new framework from Microsoft Robotics Division called "Microsoft
CCR" (Concurrency and Coordination Runtime) a few months ago in the <a href="http://msdn.microsoft.com/msdnmag/issues/06/09/ConcurrentAffairs/default.aspx">"concurrent
affairs" column at the MSDN Magazine</a> but I didn't pay much attention to it
at the time. Two weeks ago, it jumped back to my mind so I revisit
the article and started diving a little deeper into it, thinking about what sort of
problems it can solve in my world and if it does, where could I use it to our benefit.
If you don't know anything about the CCR, there is great public content published
already like the CCR <a href="http://msdn2.microsoft.com/en-us/library/bb905447.aspx">User
Guide</a> but I'll try to give you a 2 minutes intro of the general architecture.
The way CCR is built is very much like the SOA world, using messages to communicate
between "services". The major components are the Dispatcher which is actually an array
of OS Threads, the DispatcherQueue which holds a queue of delegates to run
so the Dispatcher can "look" at the DispatcherQueue and when it has a free OS
Thread available, it pulls one delegate out of the queue and run it. So far - we've
got a classic ThreadPool. There are some differences but I'll let you read about it
in the User Guide. The third component, which is the most important one is Port.
Think about Port as a pipe that can receive messages (FIFO style - first in,
first out) and hold them until someone will know what to do with them. The last component
is the "manager", the Arbiter; Arbiter expose a set of methods that allows you
to listen to a given pipe and if some conditions are met on the messages the
pipe contains, we can take the message(s) and transform them into a runnable
delegate placed in the DispatcherQueue. 
</p>
        <p>
One of the goals for this library is the make sure you've got much less places to
go wrong, by exposing a set of common async patterns you can easily use to guarantee
clean(er) code that is easier to read. Think about sending messages from one pipe
to another, creating a flow-based code via messages rather than spaghetti
code with a lot of messy indentation. This is a very powerful architecture.<br />
Obviously, the entire CCR framework is thread-safe by design so no need to protect
the library. A simple example:
</p>
        <span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">
          <p>
            <br />
            <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">using</span> (Dispatcher
dispatcher <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">new</span> Dispatcher(5, <span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4">"my_dispatcher"</span>)) <span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">//5
OS threads</span><br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">using</span> (DispatcherQueue
queue <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">new</span> DispatcherQueue(<span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4">"my_queue"</span>,
dispatcher))<br />
{<br />
    Port&lt;Uri&gt; urlsPort <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">new</span> Port&lt;Uri&gt;();<br />
    <br />
    Arbiter.Activate(queue,<br />
        Arbiter.Receive(<span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">true</span>,
urlsPort, <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">delegate</span>(Uri
uri) {<br />
            <span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">//
some code(run async!): for example we can fetch the uri content(HTML) and persist
it to your Hard Disk..</span><br />
         })<br />
    );<br /><br />
    urlsPort.Post(<span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">new</span> Uri(<span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4">"http://www.lnbogen.com"</span>));<br />
    urlsPort.Post(<span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">new</span> Uri(<span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4">"http://www.delver.com"</span>));<br />
}
</p>
        </span>
        <p>
There is no need to create an array of Threads and some sort of Queue&lt;Uri&gt; in
order to pull the items. The "ThreadPool" is implemented as part of the CCR.<br />
So far no big deal right? well, it turns out that you can easily write common patterns
with much less complexity: almost no locks, less spaghetti code and much less
code in general. 
</p>
        <p>
One of the patterns we (all of us) use a lot is the "execute-and-wait-till-finish"
pattern where you've got a list of independent items you want to run in parallel,
but you want your main thread to wait for them to finish before continue. The simplest
way to achieve it is by creating an array of Thread, activating them with a delegate
and then call Join() on each one of the Threads. Let's define a few more requirements
for this pattern:
</p>
        <ol>
          <li>
We want to be able to know about all the errors that occurred during the execution. 
</li>
          <li>
We want to be able to set a timeout so each operation(inside a Thread) won't take
more than a sensible time. 
</li>
          <li>
We want to be able to know which items were timed out and when. 
</li>
          <li>
We want to be able to know which items were completed successfully. 
</li>
          <li>
BONUS: We want to avoid writing the obvious. </li>
        </ol>
        <p>
Well, in order to implement these requirements from scratch, we need to use an outer
timer with some sort of List (for example) so each thread will "register" to it when
it begins and "unregister" when it's done. The timer should be able to interrupt the
thread and be optimized to "wake up" as soon as possible (determined by the registered
threads and which thread needs to wake up first(next in line)). In addition, we need
some sort of List of exceptions to collect all the exceptions that occurred and make
sure we lock shared objects. We'll need to use Thread[] and some sort of Queue to
enqueue\dequeue items to\from it. A lot of code for a simple pattern.<br /><br />
With Microsoft CCR it's much easier. 
<br />
Assuming that we want to handle a list of strings:
</p>
        <p>
          <span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">List&lt;<span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">string</span>&gt;
messagesToWorkOn <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">new</span> List&lt;<span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">string</span>&gt;();<br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">for</span> (<span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">int</span> i <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span> 0;
i &lt; 10; i++)<br />
   messagesToWorkOn.Add(<span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4">"message
"</span><span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">+</span> i);</span>
        </p>
        <p>
Here is the final API I've implemented on top of the CCR:
</p>
        <p>
          <span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">
            <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">using</span> (SpawnAndWaitPattern&lt;<span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">string</span>&gt; saw <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">new</span> SpawnAndWaitPattern&lt;<span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">string</span>&gt;(5, <span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4">"mythreadspool"</span>))<br />
{<br />
   AggregatedResult&lt;<span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">string</span>&gt;
result <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span> saw.Execute(messagesToWorkOn, TimeSpan.FromMilliseconds(500),<br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">                                             delegate</span>(<span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">string</span> msg)<br />
                                             {<br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">                                                if</span> (msg.Contains(<span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4">"1"</span>))<br />
                                                   Thread.Sleep(2000); <span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">//
simulate time-out</span><br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">                                                else</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">if</span> (msg.Contains(<span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4">"5"</span>))<br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">                                                   throw</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">new</span> ArgumentException(<span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4">"5
is a very bad value..."</span>); <span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">//
simulate exception</span><br />
   <br />
                                                Console.WriteLine(<span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4">"The
message: "</span><span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">+</span> msg <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">+</span><span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4">"
processed successfully."</span>);<br />
                                             });<br /><br />
   Console.WriteLine(<span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4">"Done!"</span>);<br />
   Console.WriteLine(<span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4">"Summarized
Report:\n completed results: "</span> <br />
      <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">+</span> result.SuccessfulItems.Count <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">+</span><span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4">"\n
exceptions occurred: "</span><span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">+</span> result.FaultedItems.Count <br />
      <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">+</span><span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4">"\n
timed-out results: "</span><span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">+</span> result.TimedoutItems.Count);<br />
}</span>
        </p>
        <p>
We've got 5 OS Threads, we're waiting for up to 0.5 second per item and we've got
a full result object, holding all the requirements from above.
</p>
        <p>
The code of SpawnAndWaitPattern class is quite neat and contains 0 locks (on
my behalf, the CCR manage its own locks). The CCR schedule the tasks for me; combining
it with thread-safe Port and we've got a very powerful yet simple framework
at our hands. I decided to attach the entire solution (with A LOT of
nice-green-comments) including the Ccr.Core.dll file so you could play with it:
</p>
        <p>
          <a href="http://www.lnbogen.com/content/binary/CcrPatterns.rar">CcrPatterns.rar (162.64
KB)</a>
        </p>
        <p>
Have fun.
</p>
        <img width="0" height="0" src="http://lnbogen.com/aggbug.ashx?id=b23f5c68-90b9-41a0-b18b-9069bea82c77" />
      </body>
      <title>Microsoft CCR: clean way to write parallel code in .Net</title>
      <guid isPermaLink="false">http://lnbogen.com/PermaLink,guid,b23f5c68-90b9-41a0-b18b-9069bea82c77.aspx</guid>
      <link>http://lnbogen.com/2008/02/04/MicrosoftCCRCleanWayToWriteParallelCodeInNet.aspx</link>
      <pubDate>Mon, 04 Feb 2008 04:25:12 GMT</pubDate>
      <description>&lt;p&gt;
Having to parallelize almost every bit of code here at Delver, some common patterns
emerged while we wrote a lot of back-end code.&lt;br&gt;
I remember reading about a new framework from Microsoft Robotics Division called "Microsoft
CCR" (Concurrency and Coordination Runtime)&amp;nbsp;a few months ago in the &lt;a href="http://msdn.microsoft.com/msdnmag/issues/06/09/ConcurrentAffairs/default.aspx"&gt;"concurrent
affairs" column&amp;nbsp;at the MSDN Magazine&lt;/a&gt; but I didn't pay much attention to it
at the time. Two weeks ago, it jumped back to my mind&amp;nbsp;so&amp;nbsp;I&amp;nbsp;revisit
the article and started diving a little deeper into it, thinking about what sort of
problems it can solve in my world and if it does, where could I use it&amp;nbsp;to our&amp;nbsp;benefit.
If you don't know anything about the CCR, there is great public content published
already&amp;nbsp;like the&amp;nbsp;CCR &lt;a href="http://msdn2.microsoft.com/en-us/library/bb905447.aspx"&gt;User
Guide&lt;/a&gt; but I'll try to give you a&amp;nbsp;2 minutes&amp;nbsp;intro of the general architecture.
The way CCR is built is very much like the SOA world, using messages to communicate
between "services". The major components are the Dispatcher which is actually an array
of OS Threads,&amp;nbsp;the&amp;nbsp;DispatcherQueue which holds a queue of delegates to run
so&amp;nbsp;the Dispatcher can "look" at the DispatcherQueue and when it has a free OS
Thread available, it pulls one delegate out of the queue and run it. So far - we've
got a classic ThreadPool. There are some differences but I'll let you read about it
in the User Guide. The third component, which is the most important one&amp;nbsp;is Port.
Think about Port as a pipe that can receive messages (FIFO style&amp;nbsp;- first in,
first out) and hold them until someone will know what to do with them. The last component
is the "manager", the&amp;nbsp;Arbiter; Arbiter expose a set of methods that allows you
to&amp;nbsp;listen to a given pipe and if some conditions are met on the messages the
pipe contains, we can take the message(s)&amp;nbsp;and transform them into a&amp;nbsp;runnable
delegate&amp;nbsp;placed in the DispatcherQueue. 
&lt;/p&gt;
&lt;p&gt;
One of the goals for this library is the make sure you've got much less places to
go wrong, by exposing a set of common async patterns&amp;nbsp;you can easily use to guarantee
clean(er) code that is easier to read. Think about sending messages from one pipe
to another, creating a flow-based code&amp;nbsp;via&amp;nbsp;messages&amp;nbsp;rather than spaghetti
code with a lot of messy indentation. This is a very powerful architecture.&lt;br&gt;
Obviously, the entire CCR framework is thread-safe by&amp;nbsp;design so no need to&amp;nbsp;protect
the library.&amp;nbsp;A simple example:
&lt;/p&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt; 
&lt;p&gt;
&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;using&lt;/span&gt; (Dispatcher
dispatcher &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;new&lt;/span&gt; Dispatcher(5, &lt;span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4"&gt;"my_dispatcher"&lt;/span&gt;)) &lt;span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;//5
OS threads&lt;/span&gt;
&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;using&lt;/span&gt; (DispatcherQueue
queue &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;new&lt;/span&gt; DispatcherQueue(&lt;span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4"&gt;"my_queue"&lt;/span&gt;,
dispatcher))&lt;br&gt;
{&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Port&amp;lt;Uri&amp;gt; urlsPort &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;new&lt;/span&gt; Port&amp;lt;Uri&amp;gt;();&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Arbiter.Activate(queue,&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Arbiter.Receive(&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;true&lt;/span&gt;,
urlsPort, &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;delegate&lt;/span&gt;(Uri
uri) {&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;//
some code(run async!): for example we can&amp;nbsp;fetch the uri content(HTML) and persist
it to your Hard Disk..&lt;/span&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;})&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;);&lt;br&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;urlsPort.Post(&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;new&lt;/span&gt; Uri(&lt;span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4"&gt;"http://www.lnbogen.com"&lt;/span&gt;));&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;urlsPort.Post(&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;new&lt;/span&gt; Uri(&lt;span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4"&gt;"http://www.delver.com"&lt;/span&gt;));&lt;br&gt;
}
&lt;/span&gt;&gt;
&lt;p&gt;
There is no need to create an array of Threads and some sort of Queue&amp;lt;Uri&amp;gt; in
order to pull the items. The "ThreadPool" is implemented as part of the CCR.&lt;br&gt;
So far no big deal right? well, it turns out that you can easily write common patterns
with much less complexity: almost no locks, less spaghetti code and&amp;nbsp;much less
code in general. 
&lt;/p&gt;
&lt;p&gt;
One of the patterns we (all of us)&amp;nbsp;use a lot is the "execute-and-wait-till-finish"
pattern where you've got a list of independent items you want to run in parallel,
but you want your main thread to wait for them to finish before continue. The simplest
way to achieve it is by creating an array of Thread, activating them with a delegate
and then call Join() on each one of the Threads. Let's define a few more requirements
for this pattern:
&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
We want to be able to know about all the errors that occurred during the execution. 
&lt;li&gt;
We want to be able to set a timeout so each operation(inside a Thread) won't take
more than a sensible time. 
&lt;li&gt;
We want to be able to know which items were timed out and&amp;nbsp;when. 
&lt;li&gt;
We want to be able to know which&amp;nbsp;items were completed successfully. 
&lt;li&gt;
BONUS: We want to avoid writing the obvious.&amp;nbsp;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;
Well, in order to implement these requirements from scratch, we need to use an outer
timer with some sort of List (for example) so each thread will "register" to it when
it begins and "unregister" when it's done. The timer should be able to interrupt the
thread and be optimized to "wake up" as soon as possible (determined by the registered
threads and which thread needs to wake up first(next in line)). In addition, we need
some sort of List of exceptions to collect all the exceptions that occurred and make
sure we lock shared objects. We'll need to use Thread[] and some sort of Queue to
enqueue\dequeue items to\from it.&amp;nbsp;A lot of code for a simple pattern.&lt;br&gt;
&lt;br&gt;
With Microsoft CCR it's much easier. 
&lt;br&gt;
Assuming that we want to handle a list of strings:
&lt;/p&gt;
&lt;p&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;List&amp;lt;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;string&lt;/span&gt;&amp;gt;
messagesToWorkOn &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;new&lt;/span&gt; List&amp;lt;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;string&lt;/span&gt;&amp;gt;();&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;for&lt;/span&gt; (&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;int&lt;/span&gt; i &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; 0;
i &amp;lt; 10; i++)&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;messagesToWorkOn.Add(&lt;span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4"&gt;"message
"&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;+&lt;/span&gt; i);&lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
Here is the final API I've implemented on top of the CCR:
&lt;/p&gt;
&lt;p&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;using&lt;/span&gt; (SpawnAndWaitPattern&amp;lt;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;string&lt;/span&gt;&amp;gt;&amp;nbsp;saw &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;new&lt;/span&gt; SpawnAndWaitPattern&amp;lt;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;string&lt;/span&gt;&amp;gt;(5, &lt;span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4"&gt;"mythreadspool"&lt;/span&gt;))&lt;br&gt;
{&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;AggregatedResult&amp;lt;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;string&lt;/span&gt;&amp;gt;
result &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; saw.Execute(messagesToWorkOn,&amp;nbsp;TimeSpan.FromMilliseconds(500),&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;delegate&lt;/span&gt;(&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;string&lt;/span&gt; msg)&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&lt;/span&gt; (msg.Contains(&lt;span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4"&gt;"1"&lt;/span&gt;))&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Thread.Sleep(2000); &lt;span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;//
simulate time-out&lt;/span&gt;
&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;else&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;if&lt;/span&gt; (msg.Contains(&lt;span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4"&gt;"5"&lt;/span&gt;))&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;throw&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;new&lt;/span&gt; ArgumentException(&lt;span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4"&gt;"5
is a very bad value..."&lt;/span&gt;); &lt;span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;//
simulate exception&lt;/span&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Console.WriteLine(&lt;span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4"&gt;"The
message: "&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;+&lt;/span&gt; msg &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;+&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4"&gt;"
processed successfully."&lt;/span&gt;);&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;});&lt;br&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;Console.WriteLine(&lt;span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4"&gt;"Done!"&lt;/span&gt;);&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;Console.WriteLine(&lt;span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4"&gt;"Summarized
Report:\n completed results: "&lt;/span&gt;&amp;nbsp;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;+&lt;/span&gt; result.SuccessfulItems.Count &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;+&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4"&gt;"\n
exceptions occurred: "&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;+&lt;/span&gt; result.FaultedItems.Count&amp;nbsp;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;+&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4"&gt;"\n
timed-out results: "&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;+&lt;/span&gt; result.TimedoutItems.Count);&lt;br&gt;
}&lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
We've got 5 OS Threads, we're waiting for up to 0.5 second per item and we've got
a full result object, holding all the requirements from above.
&lt;/p&gt;
&lt;p&gt;
The code of SpawnAndWaitPattern class is quite neat and contains&amp;nbsp;0 locks (on
my behalf, the CCR manage its own locks). The CCR schedule the tasks for me; combining
it with thread-safe Port and we've got a&amp;nbsp;very&amp;nbsp;powerful yet simple framework
at&amp;nbsp;our hands.&amp;nbsp;I decided to attach the entire solution (with&amp;nbsp;A LOT&amp;nbsp;of
nice-green-comments) including the Ccr.Core.dll file so you could play with it:
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://www.lnbogen.com/content/binary/CcrPatterns.rar"&gt;CcrPatterns.rar (162.64
KB)&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;
Have fun.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://lnbogen.com/aggbug.ashx?id=b23f5c68-90b9-41a0-b18b-9069bea82c77" /&gt;</description>
      <comments>http://lnbogen.com/CommentView,guid,b23f5c68-90b9-41a0-b18b-9069bea82c77.aspx</comments>
      <category>.NET</category>
      <category>.Net/Multi-Threading</category>
      <category>Microsoft CCR</category>
    </item>
    <item>
      <trackback:ping>http://lnbogen.com/Trackback.aspx?guid=3fade6f7-3cc6-4286-9974-a13eed804b62</trackback:ping>
      <pingback:server>http://lnbogen.com/pingback.aspx</pingback:server>
      <pingback:target>http://lnbogen.com/PermaLink,guid,3fade6f7-3cc6-4286-9974-a13eed804b62.aspx</pingback:target>
      <dc:creator>Oren Ellenbogen</dc:creator>
      <wfw:comment>http://lnbogen.com/CommentView,guid,3fade6f7-3cc6-4286-9974-a13eed804b62.aspx</wfw:comment>
      <wfw:commentRss>http://lnbogen.com/SyndicationService.asmx/GetEntryCommentsRss?guid=3fade6f7-3cc6-4286-9974-a13eed804b62</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
Alright alright, so I didn't post anything for... a decade or so. 
<br />
but I'm here (at the office that is) all day long, being a part of a great Team,
building the greatest\coolest piece of software I've ever dream of.<br /><br />
I promised myself that I'll be short this time so here it goes, Oren's 60 seconds
update:
</p>
        <ol>
          <li>
We've changed our name from Semingo to <strong>Delver</strong> (delver: <span showconjugation="on"><span style="WIDTH: 1pt"></span></span>(n)
deep thinker; one who investigates data). 
<br />
Hopefully (if God will hear his little buddy here), the phrase "To delve"
will catch up with the scary "Google-it". 
</li>
          <li>
We're going to show our product to the world at the <a href="http://www.demo.com/conferences/demo08/index.php">DEMO
conference</a> (28-30 January, yes, in 4 days!) in Palm Desert, CA.<br />
If you want to be one of our first beta users, please go to our site: <a href="http://www.delver.com">www.delver.com</a> and
register (we'll send you an email once we'll release our beta). 
</li>
          <li>
We're looking for super talented folks to join our amazing Team, interested?</li>
        </ol>
        <div>Short, to the point, no technical buzzzzz. I'm feeling violated.
</div>
        <div> 
</div>
        <div>
          <strong>update:</strong>
        </div>
        <div>here are a few links from interesting articles about us:
</div>
        <div> - <a href="http://www.delver.com/about.htm">http://www.delver.com/about.htm</a> (from
our home site)<br /></div>
        <div> - <span style="FONT-SIZE: 10pt; COLOR: navy; FONT-FAMILY: 'Arial','sans-serif'"><a href="http://link.brightcove.com/services/link/bcpid1127798146/bclid1396518815/bctid1392526686">http://link.brightcove.com/services/link/bcpid1127798146/bclid1396518815/bctid1392526686</a> (6
minutes of live! demo\video, presented by our CEO at DEMO conference)</span></div>
        <div>
          <span style="FONT-SIZE: 10pt; COLOR: navy; FONT-FAMILY: 'Arial','sans-serif'">
            <font face="Verdana" color="#003300">
              <span style="FONT-SIZE: 10pt; COLOR: navy; FONT-FAMILY: 'Arial','sans-serif'"> <font face="Verdana" color="#003300">- </font><a href="http://www.somewhatfrank.com/2008/02/silicon-valley.html">http://www.somewhatfrank.com/2008/02/silicon-valley.html</a> (5
minutes demo\video from IsraelWebTour 2008)</span>
            </font>
          </span>
        </div>
        <div>
          <span style="FONT-SIZE: 10pt; COLOR: navy; FONT-FAMILY: 'Arial','sans-serif'">
            <font face="Verdana" color="#003300"> - </font>
            <a href="http://www.readwriteweb.com/archives/delver_reinvents_search.php">http://www.readwriteweb.com/archives/delver_reinvents_search.php</a> (great summary
to understand our product)</span>
        </div>
        <div> - <a href="http://www.techcrunch.com/2008/01/28/delver-comes-out-of-stealth-with-a-new-twist-on-social-search/">http://www.techcrunch.com/2008/01/28/delver-comes-out-of-stealth-with-a-new-twist-on-social-search/</a></div>
        <div> - <a href="http://www.technologyreview.com/Infotech/20138/?a=f">http://www.technologyreview.com/Infotech/20138/?a=f</a><br />
 - <a href="http://www.webware.com/8301-1_109-9861049-2.html">http://www.webware.com/8301-1_109-9861049-2.html</a><br />
 - <a href="http://www.sdwys.com/2008/01/delver-delivers.html">http://www.sdwys.com/2008/01/delver-delivers.html</a><br />
 - <a href="http://mashable.com/2008/01/30/demo-08-roundup-2">http://mashable.com/2008/01/30/demo-08-roundup-2</a></div>
        <div> 
</div>
        <div> 
</div>
        <div>Next post - some cool multi-threading code and how to test it without wanting
to stick a nail in your eye (or someone's else eye). 
<br />
Now I'm feeling better...<br /></div>
        <img width="0" height="0" src="http://lnbogen.com/aggbug.ashx?id=3fade6f7-3cc6-4286-9974-a13eed804b62" />
      </body>
      <title>Semingo, Delver, Demo, What a rush!</title>
      <guid isPermaLink="false">http://lnbogen.com/PermaLink,guid,3fade6f7-3cc6-4286-9974-a13eed804b62.aspx</guid>
      <link>http://lnbogen.com/2008/01/25/SemingoDelverDemoWhatARush.aspx</link>
      <pubDate>Fri, 25 Jan 2008 10:46:58 GMT</pubDate>
      <description>&lt;p&gt;
Alright alright, so I didn't post anything for... a decade or so. 
&lt;br&gt;
but I'm here (at the office that is) all day long,&amp;nbsp;being a part of a great Team,
building the greatest\coolest piece of software I've ever dream of.&lt;br&gt;
&lt;br&gt;
I promised&amp;nbsp;myself that I'll be short this time so here it goes, Oren's 60 seconds
update:
&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
We've changed our name from Semingo&amp;nbsp;to &lt;strong&gt;Delver&lt;/strong&gt; (delver: &lt;span showconjugation="on"&gt;&lt;span style="WIDTH: 1pt"&gt;&lt;/span&gt;&lt;/span&gt;(n)
deep thinker; one who investigates data). 
&lt;br&gt;
Hopefully (if God will hear his little buddy here),&amp;nbsp;the phrase&amp;nbsp;"To delve"
will catch up&amp;nbsp;with the scary&amp;nbsp;"Google-it". 
&lt;li&gt;
We're going to show our&amp;nbsp;product to the world at the &lt;a href="http://www.demo.com/conferences/demo08/index.php"&gt;DEMO
conference&lt;/a&gt; (28-30 January, yes, in 4 days!) in Palm Desert, CA.&lt;br&gt;
If you want to be one of our first beta users, please go to our site: &lt;a href="http://www.delver.com"&gt;www.delver.com&lt;/a&gt; and
register (we'll send you an email once we'll release our beta). 
&lt;li&gt;
We're looking for super talented folks to join our amazing Team, interested?&lt;/li&gt;
&lt;/ol&gt;
&lt;div&gt;Short, to the point, no technical buzzzzz. I'm feeling violated.
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;
&lt;/div&gt;
&lt;div&gt;&lt;strong&gt;update:&lt;/strong&gt;
&lt;/div&gt;
&lt;div&gt;here are a few links from interesting articles about us:
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;- &lt;a href="http://www.delver.com/about.htm"&gt;http://www.delver.com/about.htm&lt;/a&gt; (from
our home site)&lt;br&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;- &lt;span style="FONT-SIZE: 10pt; COLOR: navy; FONT-FAMILY: 'Arial','sans-serif'"&gt;&lt;a href="http://link.brightcove.com/services/link/bcpid1127798146/bclid1396518815/bctid1392526686"&gt;http://link.brightcove.com/services/link/bcpid1127798146/bclid1396518815/bctid1392526686&lt;/a&gt;&amp;nbsp;(6
minutes of live! demo\video,&amp;nbsp;presented by our CEO at&amp;nbsp;DEMO conference)&lt;/span&gt;
&lt;/div&gt;
&lt;div&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: navy; FONT-FAMILY: 'Arial','sans-serif'"&gt;&lt;font face=Verdana color=#003300&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: navy; FONT-FAMILY: 'Arial','sans-serif'"&gt;&amp;nbsp;&lt;font face=Verdana color=#003300&gt;-&amp;nbsp;&lt;/font&gt;&lt;a href="http://www.somewhatfrank.com/2008/02/silicon-valley.html"&gt;http://www.somewhatfrank.com/2008/02/silicon-valley.html&lt;/a&gt;&amp;nbsp;(5
minutes&amp;nbsp;demo\video from IsraelWebTour 2008)&lt;/span&gt;&lt;/font&gt;&lt;/span&gt;
&lt;/div&gt;
&lt;div&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: navy; FONT-FAMILY: 'Arial','sans-serif'"&gt;&lt;font face=Verdana color=#003300&gt;&amp;nbsp;-&amp;nbsp;&lt;/font&gt;&lt;a href="http://www.readwriteweb.com/archives/delver_reinvents_search.php"&gt;http://www.readwriteweb.com/archives/delver_reinvents_search.php&lt;/a&gt;&amp;nbsp;(great&amp;nbsp;summary
to understand our product)&lt;/span&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;- &lt;a href="http://www.techcrunch.com/2008/01/28/delver-comes-out-of-stealth-with-a-new-twist-on-social-search/"&gt;http://www.techcrunch.com/2008/01/28/delver-comes-out-of-stealth-with-a-new-twist-on-social-search/&lt;/a&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;- &lt;a href="http://www.technologyreview.com/Infotech/20138/?a=f"&gt;http://www.technologyreview.com/Infotech/20138/?a=f&lt;/a&gt;
&lt;br&gt;
&amp;nbsp;- &lt;a href="http://www.webware.com/8301-1_109-9861049-2.html"&gt;http://www.webware.com/8301-1_109-9861049-2.html&lt;/a&gt;
&lt;br&gt;
&amp;nbsp;- &lt;a href="http://www.sdwys.com/2008/01/delver-delivers.html"&gt;http://www.sdwys.com/2008/01/delver-delivers.html&lt;/a&gt;
&lt;br&gt;
&amp;nbsp;- &lt;a href="http://mashable.com/2008/01/30/demo-08-roundup-2"&gt;http://mashable.com/2008/01/30/demo-08-roundup-2&lt;/a&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;
&lt;/div&gt;
&lt;div&gt;Next post - some cool multi-threading code and how to test it without wanting
to&amp;nbsp;stick a nail in your eye (or someone's else eye). 
&lt;br&gt;
Now I'm feeling better...&lt;br&gt;
&lt;/div&gt;
&lt;img width="0" height="0" src="http://lnbogen.com/aggbug.ashx?id=3fade6f7-3cc6-4286-9974-a13eed804b62" /&gt;</description>
      <comments>http://lnbogen.com/CommentView,guid,3fade6f7-3cc6-4286-9974-a13eed804b62.aspx</comments>
      <category>Life</category>
    </item>
    <item>
      <trackback:ping>http://lnbogen.com/Trackback.aspx?guid=bb39baf4-d670-4082-ace2-6748beeedb44</trackback:ping>
      <pingback:server>http://lnbogen.com/pingback.aspx</pingback:server>
      <pingback:target>http://lnbogen.com/PermaLink,guid,bb39baf4-d670-4082-ace2-6748beeedb44.aspx</pingback:target>
      <dc:creator>Oren Ellenbogen</dc:creator>
      <wfw:comment>http://lnbogen.com/CommentView,guid,bb39baf4-d670-4082-ace2-6748beeedb44.aspx</wfw:comment>
      <wfw:commentRss>http://lnbogen.com/SyndicationService.asmx/GetEntryCommentsRss?guid=bb39baf4-d670-4082-ace2-6748beeedb44</wfw:commentRss>
      <slash:comments>5</slash:comments>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p class="MsoNormal" dir="ltr" style="DIRECTION: ltr; unicode-bidi: embed; TEXT-ALIGN: left">
Imagine that you're living with one hell of a crazy wife. Every day she's
giving you bunch of tasks. "Mow the grass", "water the plants", "take out the garbage",
"replace the light in the kitchen", "build a fence" etc. For every task you complete,
she goes bananas and create 10,000 more on the spot, all <b>related</b> to the task
itself ("build a fence" leads to "paint the fence", "put a nice sign on the fence",
"practice your wax-on, wax-off" … you get the drift). Reluctant to perform all of
these tasks but smart enough to know that you'll lose at least 50% of your property
(divorce are nasty), you start collecting these tasks (you write them on papers).
You take one paper (single task), perform it and return to your wife with a big-fat
smile of your face. She, in return, creates 10,000 new <b>related</b> tasks to the
one you've just completed, write them on paper and put it in a BIG box. Every once
in a while she's not waiting for you and adding "main" tasks to the box by herself.
After performing one task, you pick another one from the box (FIFO), without knowing
if it's a main task or not, you go to your way "eager" to perform that task as requested
(as if you have a choice). This goes on and on and on… 
</p>
        <p class="MsoNormal" dir="ltr" style="DIRECTION: ltr; unicode-bidi: embed; TEXT-ALIGN: left">
The box is the tricky part here. Can one box hold billions of papers? hardly. So you
start collecting boxes and now it's getting harder as you need to add new boxes when
needed, find the "right" box to pull tasks from and making sure these boxes won't
break (maintenance) with time.
</p>
        <p class="MsoNormal" dir="ltr" style="DIRECTION: ltr; unicode-bidi: embed; TEXT-ALIGN: left">
Here are a few assumptions you can take as is:
</p>
        <ol>
          <li>
            <span>
              <span>
                <span style="FONT: 7pt 'Times New Roman'; font-size-adjust: none; font-stretch: normal">
                </span>
              </span>
            </span>
            <span dir="ltr">
            </span>Your
wife is looking for perfection but only in the "main" tasks which means that if you
were to build the fence, you have to do it perfectly so each mini task related to
it is crucial. 
</li>
          <li>
Your wife tends to forget things so you can assume that occasionally, she'll add new
"main" tasks that were already performed or exist in a different box.<span><span><span style="FONT: 7pt 'Times New Roman'; font-size-adjust: none; font-stretch: normal"></span></span></span></li>
          <li>
            <span>
              <span>
                <span style="FONT: 7pt 'Times New Roman'; font-size-adjust: none; font-stretch: normal">
                </span>
              </span>
            </span>
            <span dir="ltr">
            </span>You
can't throw away tasks "just because" as you don't know if a "mini task" will be thrown
by mistake (= your wife will be pissed off. 50% is gone.). 
</li>
          <li>
            <span>
              <span>
                <span style="FONT: 7pt 'Times New Roman'; font-size-adjust: none; font-stretch: normal">
                </span>
              </span>
            </span>
            <span dir="ltr">
            </span>Be
cool - you won't perform the same task twice. This one is on me. 
</li>
          <li>
Drinking RedBull (or XL or whatever energy drink you're familiar with) 24-7-365 you
don't need to rest. You don't need to sleep. Think robot (funny combination, for 2007). 
</li>
        </ol>
        <p class="MsoNormal" dir="ltr" style="DIRECTION: ltr; unicode-bidi: embed; TEXT-ALIGN: left">
How to store billions of tasks? 
</p>
        <p class="MsoNormal" dir="ltr" style="DIRECTION: ltr; unicode-bidi: embed; TEXT-ALIGN: left">
I kinda like the "green feeling" of a forest. Oh right, we also need them in order
to breath (El Gor is more convincing than I. Thank God). Most importantly, it costs
a lot of money buying so many papers! And the boxes!<span>  You'll need </span>a
lot of green ones ($) - not trees but we can't "breath" without them as well). Oh
well… You're starting to build a "Boxing mechanism", hire a few guys to maintain them,
getting a VC to give you some extra $$$ and after a few months\years you got it cover!
</p>
        <p class="MsoNormal" dir="ltr" style="DIRECTION: ltr; unicode-bidi: embed; TEXT-ALIGN: left">
What do you do if you don't have the extra $$$ or more important the extra time
to develop this kind of storage system?
</p>
        <p class="MsoNormal" dir="ltr" style="DIRECTION: ltr; unicode-bidi: embed; TEXT-ALIGN: left">
How to store billions of tasks? You <b>don't</b>. You <b>can't</b>.  <span></span><br />
In most scenarios, when things seem too difficult to accomplish (with the given limits)
try a different angle: "If you don't like the answer, ask a different question". 
</p>
        <p class="MsoNormal" dir="ltr" style="DIRECTION: ltr; unicode-bidi: embed; TEXT-ALIGN: left">
We know that each task creates a lot of new <b>related</b> tasks right? We also know
that keeping those new tasks is the tricky part (the BIG box problem) so what else
can be done? Let's change the question. "How do I make my wife happy?" seems like
a smarter question. If it's expensive to save those tasks why not doing these <b>related </b>tasks
on the spot instead of storing them in the box(es)? <span> </span>How is this
going to help us? Now we can throw away tasks because these tasks will be added later
on (assumption #2. Thank God your wife is not the robot). Assuming that we can save
about 1,000,000 papers in one big box – we're all set. If the box is full, we'll simply
throw away new "main" tasks, feeling good as we KNOW that we'll get to them later
on (again, assumption #2). Now all we need is one simple box with a limited amount
of papers. Less $$$ to waste and much simpler storage system to develop.
</p>
        <p class="MsoNormal" dir="ltr" style="DIRECTION: ltr; unicode-bidi: embed; TEXT-ALIGN: left">
          <br />
Crap, it just hit me. I'm doing some cool sh$% at Semingo! Join <a href="http://www.pashabitz.com/PermaLink,guid,64f43e5b-9bb7-4a2e-bc89-0420c42b0866.aspx">us</a>!
</p>
        <img width="0" height="0" src="http://lnbogen.com/aggbug.ashx?id=bb39baf4-d670-4082-ace2-6748beeedb44" />
      </body>
      <title>How to store billions of tasks?</title>
      <guid isPermaLink="false">http://lnbogen.com/PermaLink,guid,bb39baf4-d670-4082-ace2-6748beeedb44.aspx</guid>
      <link>http://lnbogen.com/2007/11/17/HowToStoreBillionsOfTasks.aspx</link>
      <pubDate>Sat, 17 Nov 2007 22:54:31 GMT</pubDate>
      <description>&lt;p class=MsoNormal dir=ltr style="DIRECTION: ltr; unicode-bidi: embed; TEXT-ALIGN: left"&gt;
Imagine that you're living with&amp;nbsp;one hell of a&amp;nbsp;crazy wife. Every day she's
giving you bunch of tasks. "Mow the grass", "water the plants", "take out the garbage",
"replace the light in the kitchen", "build a fence" etc. For every task you complete,
she goes bananas and create 10,000 more on the spot, all &lt;b&gt;related&lt;/b&gt; to the task
itself ("build a fence" leads to "paint the fence", "put a nice sign on the fence",
"practice your wax-on, wax-off" … you get the drift). Reluctant to perform all of
these tasks but smart enough to know that you'll lose at least 50% of your property
(divorce are nasty), you start collecting these tasks (you write them on papers).
You take one paper (single task), perform it and return to your wife with a big-fat
smile of your face. She, in return, creates 10,000 new &lt;b&gt;related&lt;/b&gt; tasks to the
one you've just completed, write them on paper and put it in a BIG box. Every once
in a while she's not waiting for you and adding "main" tasks to the box by herself.
After performing one task, you pick another one from the box (FIFO), without knowing
if it's a main task or not, you go to your way "eager" to perform that task as requested
(as if you have a choice). This goes on and on and on… 
&lt;/p&gt;
&lt;p class=MsoNormal dir=ltr style="DIRECTION: ltr; unicode-bidi: embed; TEXT-ALIGN: left"&gt;
The box is the tricky part here. Can one box hold billions of papers? hardly. So you
start collecting boxes and now it's getting harder as you need to add new boxes&amp;nbsp;when
needed, find the "right" box to pull tasks from and making sure these boxes won't
break (maintenance) with time.
&lt;/p&gt;
&lt;p class=MsoNormal dir=ltr style="DIRECTION: ltr; unicode-bidi: embed; TEXT-ALIGN: left"&gt;
Here are a few assumptions you can take as is:
&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;span&gt;&lt;span&gt;&lt;span style="FONT: 7pt 'Times New Roman'; font-size-adjust: none; font-stretch: normal"&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span dir=ltr&gt;&lt;/span&gt;Your
wife is looking for perfection but only in the "main" tasks which means that if you
were to build the fence, you have to do it perfectly so each mini task related to
it is crucial. 
&lt;li&gt;
Your wife tends to forget things so you can assume that occasionally, she'll add new
"main" tasks that were already performed or exist in a different box.&lt;span&gt;&lt;span&gt;&lt;span style="FONT: 7pt 'Times New Roman'; font-size-adjust: none; font-stretch: normal"&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; 
&lt;li&gt;
&lt;span&gt;&lt;span&gt;&lt;span style="FONT: 7pt 'Times New Roman'; font-size-adjust: none; font-stretch: normal"&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span dir=ltr&gt;&lt;/span&gt;You
can't throw away tasks "just because" as you don't know if a "mini task" will be thrown
by mistake (= your wife will be pissed off. 50% is gone.). 
&lt;li&gt;
&lt;span&gt;&lt;span&gt;&lt;span style="FONT: 7pt 'Times New Roman'; font-size-adjust: none; font-stretch: normal"&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span dir=ltr&gt;&lt;/span&gt;Be
cool - you won't perform the same task twice. This one is on me. 
&lt;li&gt;
Drinking RedBull (or XL or whatever energy drink you're familiar with) 24-7-365 you
don't need to rest. You don't need to sleep. Think robot (funny combination, for 2007). 
&lt;/li&gt;
&lt;/ol&gt;
&lt;p class=MsoNormal dir=ltr style="DIRECTION: ltr; unicode-bidi: embed; TEXT-ALIGN: left"&gt;
How to store billions of tasks? 
&lt;/p&gt;
&lt;p class=MsoNormal dir=ltr style="DIRECTION: ltr; unicode-bidi: embed; TEXT-ALIGN: left"&gt;
I kinda like the "green feeling" of a forest. Oh right, we also need them in order
to breath (El Gor is more convincing than I. Thank God). Most importantly, it costs
a lot of money buying&amp;nbsp;so many papers! And the boxes!&lt;span&gt;&amp;nbsp; You'll need &lt;/span&gt;a
lot of green ones ($) - not trees but we can't "breath" without them as well). Oh
well… You're starting to build a "Boxing mechanism", hire a few guys to maintain them,
getting a VC to give you some extra $$$ and after a few months\years you got it cover!
&lt;/p&gt;
&lt;p class=MsoNormal dir=ltr style="DIRECTION: ltr; unicode-bidi: embed; TEXT-ALIGN: left"&gt;
What do you do if you don't have the extra $$$ or more important&amp;nbsp;the extra time
to develop this kind of storage system?
&lt;/p&gt;
&lt;p class=MsoNormal dir=ltr style="DIRECTION: ltr; unicode-bidi: embed; TEXT-ALIGN: left"&gt;
How to store billions of tasks? You &lt;b&gt;don't&lt;/b&gt;. You &lt;b&gt;can't&lt;/b&gt;.&amp;nbsp; &lt;span&gt;&lt;/span&gt;
&lt;br&gt;
In most scenarios, when things seem too difficult to accomplish (with the given limits)
try a different angle: "If you don't like the answer, ask a different question". 
&lt;/p&gt;
&lt;p class=MsoNormal dir=ltr style="DIRECTION: ltr; unicode-bidi: embed; TEXT-ALIGN: left"&gt;
We know that each task creates a lot of new &lt;b&gt;related&lt;/b&gt; tasks right? We also know
that keeping those new tasks is the tricky part (the BIG box problem) so what else
can be done? Let's change the question. "How do I make my wife happy?" seems like
a smarter question. If it's expensive to save those tasks why not doing these &lt;b&gt;related &lt;/b&gt;tasks
on the spot instead of storing them in the box(es)? &lt;span&gt;&amp;nbsp;&lt;/span&gt;How is this
going to help us? Now we can throw away tasks because these tasks will be added later
on (assumption #2. Thank God your wife is not the robot). Assuming that we can save
about 1,000,000 papers in one big box – we're all set. If the box is full, we'll simply
throw away new "main" tasks, feeling good as we KNOW that we'll get to them later
on (again, assumption #2). Now all we need is one simple box with a limited amount
of papers. Less $$$ to waste and much simpler storage system to develop.
&lt;/p&gt;
&lt;p class=MsoNormal dir=ltr style="DIRECTION: ltr; unicode-bidi: embed; TEXT-ALIGN: left"&gt;
&lt;br&gt;
Crap, it just hit me. I'm doing some cool sh$% at Semingo! Join &lt;a href="http://www.pashabitz.com/PermaLink,guid,64f43e5b-9bb7-4a2e-bc89-0420c42b0866.aspx"&gt;us&lt;/a&gt;!
&lt;/p&gt;
&lt;img width="0" height="0" src="http://lnbogen.com/aggbug.ashx?id=bb39baf4-d670-4082-ace2-6748beeedb44" /&gt;</description>
      <comments>http://lnbogen.com/CommentView,guid,bb39baf4-d670-4082-ace2-6748beeedb44.aspx</comments>
      <category>Design</category>
    </item>
    <item>
      <trackback:ping>http://lnbogen.com/Trackback.aspx?guid=fc104328-6299-4eb1-a203-84b686aa4c5b</trackback:ping>
      <pingback:server>http://lnbogen.com/pingback.aspx</pingback:server>
      <pingback:target>http://lnbogen.com/PermaLink,guid,fc104328-6299-4eb1-a203-84b686aa4c5b.aspx</pingback:target>
      <dc:creator>Oren Ellenbogen</dc:creator>
      <wfw:comment>http://lnbogen.com/CommentView,guid,fc104328-6299-4eb1-a203-84b686aa4c5b.aspx</wfw:comment>
      <wfw:commentRss>http://lnbogen.com/SyndicationService.asmx/GetEntryCommentsRss?guid=fc104328-6299-4eb1-a203-84b686aa4c5b</wfw:commentRss>
      <slash:comments>3</slash:comments>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
Well this is mostly a good backup-post, but heck maybe a few other (<strong>VERY COOL</strong>)
geeks will find it interesting. 
<br />
Looking for some cool IDE colors\fonts, I came up with this:
</p>
        <p>
[ Regular mode ... ]
</p>
        <p>
          <img height="445" alt="ide_colors_regular.png" src="http://www.lnbogen.com/content/binary/ide_colors_regular.png" width="696" border="0" />
        </p>
        <p>
 
</p>
        <p>
[ Marking the for loop ... ]
</p>
        <p>
          <img height="449" alt="ide_colors_marking_text.png" src="http://www.lnbogen.com/content/binary/ide_colors_marking_text.png" width="662" border="0" />
        </p>
        <p>
 
</p>
        <p>
[ Output window ]
</p>
        <p>
          <img height="230" alt="ide_colors_output.png" src="http://www.lnbogen.com/content/binary/ide_colors_output.png" width="604" border="0" />
        </p>
        <p>
          <br />
I based my colors on ZenBurn.<br />
The font I'm using is Consolas.<br />
Read all about it in <a href="http://www.codinghorror.com/blog/">Jeff Atwood</a>'s <a href="http://www.codinghorror.com/blog/archives/000682.html">post</a>.
</p>
        <p>
You can download MY version here: <a href="http://www.lnbogen.com/content/binary/OrenEllenbogen_DarkSchema.rar">OrenEllenbogen_DarkSchema.rar
(58 KB)</a></p>
        <p>
          <strong>Note:</strong> if you're using ReSharper you'll have to disable the "Highlight
current line" option. 
</p>
        <img width="0" height="0" src="http://lnbogen.com/aggbug.ashx?id=fc104328-6299-4eb1-a203-84b686aa4c5b" />
      </body>
      <title>Visual Studio .Net 2005 Colors</title>
      <guid isPermaLink="false">http://lnbogen.com/PermaLink,guid,fc104328-6299-4eb1-a203-84b686aa4c5b.aspx</guid>
      <link>http://lnbogen.com/2007/11/15/VisualStudioNet2005Colors.aspx</link>
      <pubDate>Thu, 15 Nov 2007 10:34:24 GMT</pubDate>
      <description>&lt;p&gt;
Well this is mostly a good backup-post, but heck maybe a few other (&lt;strong&gt;VERY COOL&lt;/strong&gt;)
geeks will find it interesting. 
&lt;br&gt;
Looking for some cool IDE colors\fonts, I came up with this:
&lt;/p&gt;
&lt;p&gt;
[ Regular mode ...&amp;nbsp;]
&lt;/p&gt;
&lt;p&gt;
&lt;img height=445 alt=ide_colors_regular.png src="http://www.lnbogen.com/content/binary/ide_colors_regular.png" width=696 border=0&gt;
&lt;/p&gt;
&lt;p&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p&gt;
[ Marking the for loop&amp;nbsp;... ]
&lt;/p&gt;
&lt;p&gt;
&lt;img height=449 alt=ide_colors_marking_text.png src="http://www.lnbogen.com/content/binary/ide_colors_marking_text.png" width=662 border=0&gt;
&lt;/p&gt;
&lt;p&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p&gt;
[ Output window ]
&lt;/p&gt;
&lt;p&gt;
&lt;img height=230 alt=ide_colors_output.png src="http://www.lnbogen.com/content/binary/ide_colors_output.png" width=604 border=0&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;br&gt;
I based my colors on ZenBurn.&lt;br&gt;
The font I'm using is Consolas.&lt;br&gt;
Read all about it in &lt;a href="http://www.codinghorror.com/blog/"&gt;Jeff Atwood&lt;/a&gt;'s&amp;nbsp;&lt;a href="http://www.codinghorror.com/blog/archives/000682.html"&gt;post&lt;/a&gt;.
&lt;/p&gt;
&lt;p&gt;
You can download MY version here: &lt;a href="http://www.lnbogen.com/content/binary/OrenEllenbogen_DarkSchema.rar"&gt;OrenEllenbogen_DarkSchema.rar
(58 KB)&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;Note:&lt;/strong&gt; if you're using ReSharper you'll have to disable the "Highlight
current line" option.&amp;nbsp;
&lt;/p&gt;
&lt;img width="0" height="0" src="http://lnbogen.com/aggbug.ashx?id=fc104328-6299-4eb1-a203-84b686aa4c5b" /&gt;</description>
      <comments>http://lnbogen.com/CommentView,guid,fc104328-6299-4eb1-a203-84b686aa4c5b.aspx</comments>
      <category>.NET/Visual Studio .Net 2005</category>
    </item>
    <item>
      <trackback:ping>http://lnbogen.com/Trackback.aspx?guid=8f4e3577-8db6-4890-a66d-7c124367dece</trackback:ping>
      <pingback:server>http://lnbogen.com/pingback.aspx</pingback:server>
      <pingback:target>http://lnbogen.com/PermaLink,guid,8f4e3577-8db6-4890-a66d-7c124367dece.aspx</pingback:target>
      <dc:creator>Oren Ellenbogen</dc:creator>
      <wfw:comment>http://lnbogen.com/CommentView,guid,8f4e3577-8db6-4890-a66d-7c124367dece.aspx</wfw:comment>
      <wfw:commentRss>http://lnbogen.com/SyndicationService.asmx/GetEntryCommentsRss?guid=8f4e3577-8db6-4890-a66d-7c124367dece</wfw:commentRss>
      <slash:comments>6</slash:comments>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
What is more important to you - having the brightest dude in the world in your
team, doing his magic with God-like authority or real "together-will-conquer-the-world"
Team work? Tricky question... 
</p>
        <p>
          <img height="126" alt="house_tv_show.jpg" src="http://www.lnbogen.com/content/binary/house_tv_show.jpg" width="388" border="0" />  
<br /><br />
For those of you who don't know the TV series "House", this is your wake up call!
Go see it. Now. Seriously.<br />
Well, if you don't have the time or you're just too damn eager to read my post, we'll,
"you're an idiot!", but that's your right so I'll give you a short summary: Dr. House,
played by the genius actor Hugh Laurie, is the go-to-guy for all the rare cases where
the rest of the doctors go bananas. With his extremely cynical point of view
and shameless wittiness, combined with a very bright, analytic and (yet) creative
thinking, he manage to solve all (we'll, almost) of these cases and still being a
complete jerk to his "teammates" during the show. Just a few pearls from <a href="http://en.wikiquote.org/wiki/House_(TV_series)">Wikiquote</a> so
you'll get the drift:
</p>
        <p>
          <strong>         Dr. Cuddy:</strong> You
don't prescribe medicine based on guesses. At least we don't since Tuskeegee and Mengele. <br /><strong>         Dr. House:</strong> You're
comparing me to a Nazi? [admiringly] Nice ... 
</p>
        <dd>
          <b>Lucille</b>: I'm not pregnant. 
<dd><b>Dr. House</b>: Sorry, you don't get to make that call unless you have a stethoscope.
Union rules.<br /><p>
If you ask me, I would pick House any day. Now, if any of you know such a man, let
him know that we're at Semingo are hiring; Till then, I guess that I would stick to
a strong Team and real commitment instead of software-Nazi. 
</p><p>
I'm lying. I don't think that following someone blindly is for me. I don't believe in
this kind of leadership. I grew up at the court, playing Basketball since I was
~9, there is nothing I love more than genuine Team spirit. Facing the fact that "white
man can't jump" quite early in my life, I realized that Michael Jordan can be rest
assured, I'm not going to steal his glory. Knowing that and still being the competitive
guy that I am, there is no other choice but to build a strong Team and having fun
together. It worked for me so far.
</p><p>
Shame though, It would have been funny working with someone like House; If only life
were a TV show...
</p></dd><img width="0" height="0" src="http://lnbogen.com/aggbug.ashx?id=8f4e3577-8db6-4890-a66d-7c124367dece" /></dd>
      </body>
      <title>Can you build software like House ?</title>
      <guid isPermaLink="false">http://lnbogen.com/PermaLink,guid,8f4e3577-8db6-4890-a66d-7c124367dece.aspx</guid>
      <link>http://lnbogen.com/2007/10/20/CanYouBuildSoftwareLikeHouse.aspx</link>
      <pubDate>Sat, 20 Oct 2007 03:16:42 GMT</pubDate>
      <description>&lt;p&gt;
What is more important to&amp;nbsp;you - having the brightest dude in the world in your
team, doing his magic with God-like authority or real "together-will-conquer-the-world"
Team work? Tricky question... 
&lt;/p&gt;
&lt;p&gt;
&lt;img height=126 alt=house_tv_show.jpg src="http://www.lnbogen.com/content/binary/house_tv_show.jpg" width=388 border=0&gt;&amp;nbsp; 
&lt;br&gt;
&lt;br&gt;
For those of you who don't know the TV series "House", this is your wake up call!
Go see it. Now. Seriously.&lt;br&gt;
Well, if you don't have the time or you're just too damn eager to read my post, we'll,
"you're an idiot!", but that's your right so I'll give you a short summary: Dr. House,
played by the genius actor Hugh Laurie, is the go-to-guy for all the rare cases where
the rest of the doctors&amp;nbsp;go bananas. With his extremely cynical point of view
and shameless wittiness, combined with a very bright, analytic and (yet) creative
thinking, he manage to solve all (we'll, almost) of these cases and still being a
complete jerk to his "teammates" during the show. Just a few pearls from &lt;a href="http://en.wikiquote.org/wiki/House_(TV_series)"&gt;Wikiquote&lt;/a&gt; so
you'll get the drift:
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Dr. Cuddy:&lt;/strong&gt; You
don't prescribe medicine based on guesses. At least we don't since Tuskeegee and Mengele.&amp;nbsp;&lt;br&gt;
&lt;strong&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Dr. House:&lt;/strong&gt; You're
comparing me to a Nazi? [admiringly] Nice ... 
&lt;/p&gt;
&lt;dd&gt;
&lt;b&gt;Lucille&lt;/b&gt;: I'm not pregnant. 
&lt;dd&gt;
&lt;b&gt;Dr. House&lt;/b&gt;: Sorry, you don't get to make that call unless you have a stethoscope.
Union rules.&lt;br&gt;
&lt;p&gt;
If you ask me, I would pick House any day. Now, if any of you know such a man, let
him know that we're at Semingo are hiring; Till then, I guess that I would stick to
a strong Team and real commitment instead of software-Nazi. 
&lt;/p&gt;
&lt;p&gt;
I'm lying. I don't think that following someone blindly is for me. I don't believe&amp;nbsp;in
this kind of leadership.&amp;nbsp;I grew up at the court, playing Basketball since I was
~9, there is nothing I love more than genuine Team spirit. Facing the fact that "white
man can't jump" quite early in my life, I realized that Michael Jordan can be rest
assured, I'm not going to steal his glory. Knowing that and still being the competitive
guy that I am, there is no other choice but to build a strong Team and having fun
together.&amp;nbsp;It worked for me so far.
&lt;/p&gt;
&lt;p&gt;
Shame though, It would have been funny working with someone like House; If only life
were a&amp;nbsp;TV show...
&lt;/p&gt;
&lt;/dd&gt;&lt;img width="0" height="0" src="http://lnbogen.com/aggbug.ashx?id=8f4e3577-8db6-4890-a66d-7c124367dece" /&gt;</description>
      <comments>http://lnbogen.com/CommentView,guid,8f4e3577-8db6-4890-a66d-7c124367dece.aspx</comments>
      <category>Management</category>
    </item>
    <item>
      <trackback:ping>http://lnbogen.com/Trackback.aspx?guid=c8ddd489-b0cb-4c08-8e47-759cbe20f3c0</trackback:ping>
      <pingback:server>http://lnbogen.com/pingback.aspx</pingback:server>
      <pingback:target>http://lnbogen.com/PermaLink,guid,c8ddd489-b0cb-4c08-8e47-759cbe20f3c0.aspx</pingback:target>
      <dc:creator>Oren Ellenbogen</dc:creator>
      <wfw:comment>http://lnbogen.com/CommentView,guid,c8ddd489-b0cb-4c08-8e47-759cbe20f3c0.aspx</wfw:comment>
      <wfw:commentRss>http://lnbogen.com/SyndicationService.asmx/GetEntryCommentsRss?guid=c8ddd489-b0cb-4c08-8e47-759cbe20f3c0</wfw:commentRss>
      <slash:comments>1</slash:comments>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
          <a href="http://blog.karmona.com/">Moti</a> and I have <a href="http://blog.karmona.com/index.php/2007/10/09/scrum-clan/">decided</a> to
form an invite-only <strong>Scrum Clan</strong>.<br />
We would like to tag <a title="Pasha Bitz" href="http://www.pashabitz.com/">Pasha
Bitz</a> (snapshot below) as the 3rd clan member.
</p>
        <p>
          <img height="195" alt="Pasha_Scrum_Lover.jpg" src="http://www.lnbogen.com/content/binary/Pasha_Scrum_Lover.jpg" width="241" border="0" />
        </p>
        <p>
Pasha, choose carefully, you can only tag <u>one</u> Scrum-Lover like yourself to
this distinguish clan ;)
</p>
        <p>
          <strong>
            <br />
p.s </strong>- If you want to be part of the Scrum Clan, please drop a comment
and you <em>*might*</em> get an invitation...
</p>
        <p>
          <strong>
            <font size="4">                                                     </font>
          </strong>
        </p>
        <p>
          <strong>
            <font size="4">                                 </font>
            <font size="5">Scrum
Rules !</font>
          </strong>
        </p>
        <img width="0" height="0" src="http://lnbogen.com/aggbug.ashx?id=c8ddd489-b0cb-4c08-8e47-759cbe20f3c0" />
      </body>
      <title>Scrum Clan</title>
      <guid isPermaLink="false">http://lnbogen.com/PermaLink,guid,c8ddd489-b0cb-4c08-8e47-759cbe20f3c0.aspx</guid>
      <link>http://lnbogen.com/2007/10/09/ScrumClan.aspx</link>
      <pubDate>Tue, 09 Oct 2007 22:47:34 GMT</pubDate>
      <description>&lt;p&gt;
&lt;a href="http://blog.karmona.com/"&gt;Moti&lt;/a&gt;&amp;nbsp;and I have &lt;a href="http://blog.karmona.com/index.php/2007/10/09/scrum-clan/"&gt;decided&lt;/a&gt; to
form an invite-only &lt;strong&gt;Scrum Clan&lt;/strong&gt;.&lt;br&gt;
We would like to tag &lt;a title="Pasha Bitz" href="http://www.pashabitz.com/"&gt;Pasha
Bitz&lt;/a&gt; (snapshot below) as the 3rd clan member.
&lt;/p&gt;
&lt;p&gt;
&lt;img height=195 alt=Pasha_Scrum_Lover.jpg src="http://www.lnbogen.com/content/binary/Pasha_Scrum_Lover.jpg" width=241 border=0&gt;
&lt;/p&gt;
&lt;p&gt;
Pasha, choose carefully, you can only tag &lt;u&gt;one&lt;/u&gt; Scrum-Lover like yourself to
this distinguish clan ;)
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;
&lt;br&gt;
p.s &lt;/strong&gt;- If you want to be part of the Scrum Clan, please drop&amp;nbsp;a comment
and you &lt;em&gt;*might*&lt;/em&gt; get an invitation...
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;&lt;font size=4&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/font&gt;&lt;/strong&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;&lt;font size=4&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font size=5&gt;Scrum
Rules !&lt;/font&gt;&lt;/strong&gt;
&lt;/p&gt;
&lt;img width="0" height="0" src="http://lnbogen.com/aggbug.ashx?id=c8ddd489-b0cb-4c08-8e47-759cbe20f3c0" /&gt;</description>
      <comments>http://lnbogen.com/CommentView,guid,c8ddd489-b0cb-4c08-8e47-759cbe20f3c0.aspx</comments>
      <category>Scrum</category>
    </item>
    <item>
      <trackback:ping>http://lnbogen.com/Trackback.aspx?guid=32565423-11a0-4e72-aef4-8667884ef8d7</trackback:ping>
      <pingback:server>http://lnbogen.com/pingback.aspx</pingback:server>
      <pingback:target>http://lnbogen.com/PermaLink,guid,32565423-11a0-4e72-aef4-8667884ef8d7.aspx</pingback:target>
      <dc:creator>Oren Ellenbogen</dc:creator>
      <wfw:comment>http://lnbogen.com/CommentView,guid,32565423-11a0-4e72-aef4-8667884ef8d7.aspx</wfw:comment>
      <wfw:commentRss>http://lnbogen.com/SyndicationService.asmx/GetEntryCommentsRss?guid=32565423-11a0-4e72-aef4-8667884ef8d7</wfw:commentRss>
      <slash:comments>1</slash:comments>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
Let me start with an out-loud recap of this post: Agile is not something you can put
on a bread nor is it "a certain path to success". 
</p>
        <p>
          <strong>It's about STATE OF MIND.</strong>
        </p>
        <p>
If I had to describe the meaning of "Agile" to a new teammate I would say: Agile is
a constant thinking about how we, AS A TEAM, can produce working features to our users
with high quality within a short time-frame. 
<br /><br />
Don't worry:<br />
It's really OK to provide only a subset of feature(s) in one sprint. 
<br />
It's really OK to leave SOME designing\architecture issues for later on as long as
the high-level architecture is good enough (=you're comfortable with it) to answer
the big questions.<br />
It's really OK to implement only two REALLY-DONE-HIGH-QUALITY features in one sprint
over four semi-working-not-demoable features.<br /></p>
        <p>
The key here though is not really the practices, it's about the big bullets(again,
state of mind):
</p>
        <p>
1). Produce value for your customers and adjust\adopt early. 
<br />
2). Build a Team (self leadership).
</p>
        <p>
These ideas are hard to implement and require special kind of people. Putting
the Team in front of yourself is not a very job-secure attitude.  The ability
to help your teammates, shift tasks, taking ownership, critisize yourself and your
teammates and getting better, produce high quality design, tests and code - all of
it - requires versatile people with unique state of mind (and unique abilities,
of course). It's worth it. When things glue, it's a real magic; Things start to get
going by the Team, improvements and features starting to come from the developers\QA\Graphic
Designer, adjustments are made on a regular basis, changes are welcome and productivity
is <strong>celebrated</strong>. 
</p>
        <p>
You can feel something is going right. 
<br />
That's Agile.
</p>
        <img width="0" height="0" src="http://lnbogen.com/aggbug.ashx?id=32565423-11a0-4e72-aef4-8667884ef8d7" />
      </body>
      <title>No, THAT is not Agile</title>
      <guid isPermaLink="false">http://lnbogen.com/PermaLink,guid,32565423-11a0-4e72-aef4-8667884ef8d7.aspx</guid>
      <link>http://lnbogen.com/2007/09/10/NoTHATIsNotAgile.aspx</link>
      <pubDate>Mon, 10 Sep 2007 18:21:03 GMT</pubDate>
      <description>&lt;p&gt;
Let me start with an out-loud recap of this post: Agile is not something you can put
on a bread nor is it "a certain path to success". 
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;It's about STATE OF MIND.&lt;/strong&gt;
&lt;/p&gt;
&lt;p&gt;
If I had to describe the meaning of "Agile" to a new teammate I would say: Agile is
a constant thinking about how we, AS A TEAM, can produce working features to our users
with high quality within a short time-frame. 
&lt;br&gt;
&lt;br&gt;
Don't worry:&lt;br&gt;
It's really OK to provide only a subset of feature(s) in one sprint. 
&lt;br&gt;
It's really OK to leave SOME designing\architecture issues for later on as long as
the high-level architecture is good enough (=you're comfortable with it) to answer
the big questions.&lt;br&gt;
It's really OK to implement only two REALLY-DONE-HIGH-QUALITY features in one sprint
over four semi-working-not-demoable features.&lt;br&gt;
&lt;/p&gt;
&lt;p&gt;
The key here though is not really the practices, it's about the big bullets(again,
state of mind):
&lt;/p&gt;
&lt;p&gt;
1). Produce value for your customers and adjust\adopt early. 
&lt;br&gt;
2). Build a Team (self leadership).
&lt;/p&gt;
&lt;p&gt;
These ideas are hard to&amp;nbsp;implement and require special&amp;nbsp;kind of people. Putting
the Team in front of yourself is not a very job-secure attitude.&amp;nbsp; The ability
to help your teammates, shift tasks, taking ownership, critisize yourself and your
teammates and getting better, produce high quality design, tests and code - all of
it&amp;nbsp;- requires versatile people with unique state of mind (and unique abilities,
of course). It's worth it. When things glue, it's a real magic; Things start to get
going by the Team, improvements and features starting to come from the developers\QA\Graphic
Designer, adjustments are made on a regular basis, changes are welcome and productivity
is &lt;strong&gt;celebrated&lt;/strong&gt;. 
&lt;/p&gt;
&lt;p&gt;
You can feel something is going right. 
&lt;br&gt;
That's Agile.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://lnbogen.com/aggbug.ashx?id=32565423-11a0-4e72-aef4-8667884ef8d7" /&gt;</description>
      <comments>http://lnbogen.com/CommentView,guid,32565423-11a0-4e72-aef4-8667884ef8d7.aspx</comments>
      <category>Agile</category>
    </item>
    <item>
      <trackback:ping>http://lnbogen.com/Trackback.aspx?guid=76dbf68b-8dd6-4ebb-ab89-11a7b93f58d5</trackback:ping>
      <pingback:server>http://lnbogen.com/pingback.aspx</pingback:server>
      <pingback:target>http://lnbogen.com/PermaLink,guid,76dbf68b-8dd6-4ebb-ab89-11a7b93f58d5.aspx</pingback:target>
      <dc:creator>Oren Ellenbogen</dc:creator>
      <wfw:comment>http://lnbogen.com/CommentView,guid,76dbf68b-8dd6-4ebb-ab89-11a7b93f58d5.aspx</wfw:comment>
      <wfw:commentRss>http://lnbogen.com/SyndicationService.asmx/GetEntryCommentsRss?guid=76dbf68b-8dd6-4ebb-ab89-11a7b93f58d5</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
The way WCF proxies are designed is to live until shi* happens. 
<br /><br />
Let's assume that we have a CalcualtorService with one method named Divide(int a,
int b). Sasha, a cool programmer-dude, trying to produce some usefull software
writes:
</p>
        <p>
          <span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">
            <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">public</span> MyCalcualtorForm
: Form {<br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"><br />
   private</span> CalculatorProxy _calc <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">new</span> CalculatorProxy();<br /><br />
   Calc_Click(...) {<br />
      _calc.Divide(firstNumber, secondNumber);<br />
   }<br />
}<br /></span>
        </p>
        <p>
What is the first error you can think of that could happen? Yep, DivideByZeroException.<br />
Once the proxy gets an exception, it enters into a "Faulted" state which makes the
proxy unusable(=you cannot use it again). 
<br />
The quickest solution is to work "by the book" and create a new instance each and
every time we need to call the service:
</p>
        <p>
          <span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">Calc_Click(...)
{<br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">   using</span> (CalculatorProxy
calc <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">new</span> CalculatorProxy())<br />
      calc.Divide(firstNumber, secondNumber);<br />
}<br /></span>
        </p>
        <p>
But what's bad in this solution?
</p>
        <ol>
          <li>
Performance - you pay (not a lot but neither little) for each creation of the proxy.
Sure, it will probably not be your bottleneck, but heck, why is it useful? Most of
the time the proxy will not throw an exception and yet we need to create it every
time just to avoid the faulted state scenario.  
</li>
          <li>
Design - If we declare this exception BY CONTRACT, I would expect that the proxy will
still be usable afterwards. Do we really want to return Enum\int\string as status
instead of throwing exception just because of poor design? 
</li>
          <li>
TDD - you know that I'm in love with it. Now imagine Dependency Injection. Component
A recieve ICalculatorProxy and use it to... calculate something. Working "by the book"
is no good as we want to recieve an instance of the proxy from the outside in
order to mock it. Right, so we inject a proxy from the outside (got to love
Windsor) and life is pretty sweeet. Darn! Wait! one poor (even by design) exception
and our proxy goes dead. Very un-TDDish of Microsoft.</li>
        </ol>
        <p>
I had to come with a solution as no one will take TDD away from me. I present
to you ProtectedProxy: this little IL-code-at-the-end-of-the-day will able
you to recover from faulted state by creating a new proxy on each exception thus making
your proxy... useable (couldn't think about a better word to describe it). Think about
a situation where your proxy is trying to call the service but the service is down; In
Semingo, we decided that we want to keep trying until the service is up. Via ProtectedProxy,
you can determine how many times do you want to recover and when you should finally
kill the proxy. Oh yea, ProtectedProxy uses Windsor in order to create new proxies
if needed and logging messages to log4net. Good stuff.
</p>
        <p>
In the example above, all Sasha had to do was to:<br />
1). Initialize the _calc field by:<br />
        ProtectedProxy&lt;ICalculatorProxy&gt;
_calc = new ProtectedProxy&lt;ICalculatorProxy&gt;(new CalculatorProxy());<br />
2). call _calc via:<br />
        _calc.Instance.Divide(firstNumber, secondNumber);<br /><br />
But enough said, code please:
</p>
        <p>
          <span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">
            <span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">//
Written by Oren Ellenbogen (07.08.07) - trying to protect our proxies so they could
recover from:</span>
            <br />
            <span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">//
(A) The service is not up yet, but we want to try again later.</span>
            <br />
            <span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">//
(B) The service throws (ANY) exception, we still want our proxy to function (bubble
the exception, but still keep on working).</span>
            <br />
            <span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">//
Microsoft intended to use a NEW proxy per call, but for TDD this is not ideal as we
would like to inject proxies from outside as mocks</span>
            <br />
            <span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">//
in order to simulate multiple scenarios. </span>
            <br />
            <br />
            <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">#region</span>
            <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">using</span>
            <br />
            <br />
            <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">using</span> System;<br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">using</span> System.Reflection;<br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">using</span> System.ServiceModel;<br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">using</span> Castle.Core.Resource;<br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">using</span> Castle.Windsor;<br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">using</span> Castle.Windsor.Configuration.Interpreters;<br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">using</span> log4net; 
<br /><br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">#endregion</span><br /><br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">namespace</span> Semingo.Services.Proxies.Helpers<br />
{<br /></span>
          <span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">   <br />
   <font color="#0000ff">public</font><font color="#0000ff">interface</font> IProxy
: ICommunicationObject { <br />
      <font color="#0000ff">bool</font> Ping();<br />
   }</span>
        </p>
        <div>
          <span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">
            <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">   </span>
            <span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">///
&lt;summary&gt;</span>
            <br />
            <span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">   ///
Protect proxy from entering Faulted state by re-creating the proxy via Windsor Container
on Faulted.</span>
            <br />
            <span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">   ///
IMPORTANT: that even if a fatal exception is raised by the service (for example: the
service is not up yet), the proxy will be raised again. <br />
   /// Use it wisely (TIP: you CAN determine the number of 'recovery'
attempts).</span>
            <br />
            <span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">   ///
&lt;/summary&gt;</span>
            <br />
            <span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">   ///
&lt;typeparam name="I"&gt;The proxy interface to protect&lt;/typeparam&gt;</span>
            <br />
            <span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">   ///
&lt;remarks&gt;</span>
            <br />
            <span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">   ///
The way WCF works is that ANY exception on the service will cause the proxy to enter
"faulted" state which means you can not use it anymore.</span>
            <br />
            <span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">   ///
Imagine a service of CalculatorService that expose the method float Divide(int a,
int b). Sending b=0 will raise an exception in the service</span>
            <br />
            <span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">   ///
and the proxy will get into faulted state. This is not ideal as the proxy itself should
be used again.</span>
            <br />
            <span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">   ///
&lt;/remarks&gt;</span>
            <br />
            <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">   public</span>
            <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">class</span> ProtectedProxy&lt;I&gt;
: IDisposable<br />
      where I : <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"><font color="#000000">IProxy</font></span><br />
   {<br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">      private</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">static</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">readonly</span> ILog
_logger <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span> LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); <br /><br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">      private</span> I
_instance;<br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">      private</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">readonly</span> IWindsorContainer
_container;<br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">      private</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">int</span> _faultedCounter <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span> 0;<br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">      private</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">bool</span> _disposed <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">false</span>;<br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">      private</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">const</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">int</span> AlertableNumberOfFaultedTimes <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span> 10; <br /><br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">      public</span> ProtectedProxy(I
instance)<br />
         : <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">this</span>(CreateXmlBasedWindsorContainer(),
instance)<br />
      {   <br />
      } <br /><br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">      public</span> ProtectedProxy(IWindsorContainer
container, I instance)<br />
      {<br />
         _container <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span> container;<br />
         ShieldInstance(instance);<br />
      } <br /><br /><span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">      ///
&lt;summary&gt;</span><br /><span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">      ///
Returns the number of faults this proxy had so far</span><br /><span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">      ///
&lt;/summary&gt;</span><br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">      public</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">int</span> NumberOfFaults<br />
      {<br />
         get { <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">return</span> _faultedCounter;
}<br />
      } <br /><br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">      public</span> I
Instance<br />
      {<br />
         get<br />
         {<br />
            ThrowIfInstanceAlreadyDisposed(); <br /><br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">            if</span> (_instance.State
== CommunicationState.Faulted || _instance.State == CommunicationState.Closed || _instance.State
== CommunicationState.Closing)<br />
               {<br />
                  _logger.Warn(<span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4">"Notice:
The proxy state is invalid ("</span><span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">+</span> communicationObj.State <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">+</span><span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4">").
The Faulted event should have been raised and handle this state - this need to be
checked."</span>);<br />
                  HandleFaultedInstance();<br />
               }<br /><br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">            return</span> _instance;<br />
         }<br />
      } <br /><br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">      public</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">void</span> Close()<br />
      {<br />
         Dispose();<br />
      } <br /><br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">      private</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">void</span> ThrowIfInstanceAlreadyDisposed()<br />
      {<br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">         if</span> (_disposed)<br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">            throw</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">new</span> ObjectDisposedException(<span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4">"The
protected proxy for the type: "</span><span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">+</span> _instance.GetType().FullName <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">+</span><span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4">"
was closed. Cannot return a live instance of this type."</span>);<br />
      } <br /><br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">      private</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">void</span> ShieldInstance(I
instance)<br />
      {<br />
         _instance <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span> instance; <br />
         _instance.Faulted += <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">delegate</span> {
HandleFaultedInstance(); };<br />
      } <br /><br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">      private</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">void</span> HandleFaultedInstance()<br />
      {<br />
         ThrowIfInstanceAlreadyDisposed(); <br /><br />
         _faultedCounter++; <br /><br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">         if</span> (_faultedCounter
&gt;= AlertableNumberOfFaultedTimes)<br />
            _logger.Warn(<span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4">"ALERT!
The proxy for the type "</span><span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">+</span> _instance.GetType().FullName <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">+</span><span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4">"
got faulted for the "</span><span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">+</span> _faultedCounter <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">+</span><span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4">"
time. Recreating the proxy but we must verify if this is valid."</span>);<br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">         else</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">if</span> (_logger.IsDebugEnabled)<br />
            _logger.Debug(<span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4">"Proxy
for type "</span><span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">+</span> _instance.GetType().FullName <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">+</span><span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4">"
got faulted (current state: "</span><span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">+</span> ((ICommunicationObject)_instance).State <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">+</span><span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4">")
- recreating the proxy. Number of faulted instances so far: "</span><span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">+</span> _faultedCounter <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">+</span><span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4">"."</span>); <br /><br />
         ProxyHelper.CloseProxy(_instance); <span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">//
close current proxy</span><br />
         ShieldInstance(_container.Resolve&lt;I&gt;()); <span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">//
re-create the proxy, faulted proxies are no good for further use.</span><br />
      } <br /><br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">      private</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">static</span> IWindsorContainer
CreateXmlBasedWindsorContainer()<br />
      {<br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">         try</span><br />
         {<br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">            return</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">new</span> WindsorContainer(<span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">new</span> XmlInterpreter(<span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">new</span> ConfigResource(<span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4">"castle"</span>)));<br />
         }<br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">         catch</span> (Exception
err)<br />
         {<br />
            _logger.Warn(<span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4">"Unable
to create xml based windsor container, using empty one."</span>, err);<br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">            return</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">new</span> WindsorContainer(); <span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">//
for testing (the proxy will be mocked anyway).</span><br />
         }<br />
      } <br /><br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">      #region</span> IDisposable
Members <br /><br /><span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">      ///&lt;summary&gt;</span><br /><span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">      ///Performs
application-defined tasks associated with freeing, releasing, or resetting unmanaged
resources.</span><br /><span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">      ///&lt;/summary&gt;</span><br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">      public</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">void</span> Dispose()<br />
      {<br />
         Dispose(<span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">true</span>);<br />
         GC.SuppressFinalize(<span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">this</span>);<br />
      } <br /><br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">      protected</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">virtual</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">void</span> Dispose(<span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">bool</span> disposing)<br />
      {<br />
         _logger.Info(<span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4">"Attempting
to dispose the protected proxy for the type: "</span><span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">+</span> _instance.GetType().FullName <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">+</span><span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4">",
disposed already? "</span><span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">+</span> _disposed); <br /><br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">         if</span> (_disposed) <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">return</span>; <br /><br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">         if</span> (disposing)<br />
         {<br />
            ProxyHelper.CloseProxy(_instance);<br />
         } <br /><br />
         _disposed <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">true</span>;<br />
      } <br /><br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">      #endregion</span><br />
   }<br /><br /><br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">   public</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">static</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">class</span> ProxyHelper<br />
   {<br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">      private</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">static</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">readonly</span> ILog
_logger <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span> LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); <br /><br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">      public</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">static</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">void</span> CloseProxy(<span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">object</span> proxy)<br />
      {<br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">         if</span> (proxy
== <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">null</span>) <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">return</span>; <br />
         CloseProxy(proxy <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">as</span> ICommunicationObject);<br />
      } <br /><br /><span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">      ///
&lt;summary&gt;</span><br /><span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">      ///
Close the proxy in a safe manner (will not throw exception)</span><br /><span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">      ///
&lt;/summary&gt;</span><br /><span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">      ///
&lt;param name="proxy"&gt;The proxy to close&lt;/param&gt;</span><br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">      public</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">static</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">void</span> CloseProxy(ICommunicationObject
proxy)<br />
      {<br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">         if</span> (proxy
== <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">null</span>) <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">return</span>; <br /><br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">         try</span><br />
         {<br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">            if</span> (proxy.State
== CommunicationState.Closing || proxy.State == CommunicationState.Closed || proxy.State
== CommunicationState.Faulted)<br />
               proxy.Abort();<br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">            else</span><br />
               proxy.Close();<br />
         }<br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">         catch</span> (CommunicationException)<br />
         {<br />
            proxy.Abort();<br />
         }<br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">         catch</span> (TimeoutException)<br />
         {<br />
            proxy.Abort();<br />
         }<br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">         catch</span> (Exception
err)<br />
         {<br />
            _logger.Error(err);<br />
            proxy.Abort();<br />
         }<br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">         finally</span><br />
         {<br />
            proxy <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">null</span>;<br />
      }<br /></span>
          <span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">   }<br />
}</span>
          <span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">
            <br />
          </span>
        </div>
        <p>
Hours of joy...
</p>
        <p>
Almost forgot, on the next post - "How to TDD WCF code" - stay tuned...
</p>
        <img width="0" height="0" src="http://lnbogen.com/aggbug.ashx?id=76dbf68b-8dd6-4ebb-ab89-11a7b93f58d5" />
      </body>
      <title>Making WCF Proxy useable</title>
      <guid isPermaLink="false">http://lnbogen.com/PermaLink,guid,76dbf68b-8dd6-4ebb-ab89-11a7b93f58d5.aspx</guid>
      <link>http://lnbogen.com/2007/09/05/MakingWCFProxyUseable.aspx</link>
      <pubDate>Wed, 05 Sep 2007 22:23:59 GMT</pubDate>
      <description>&lt;p&gt;
The way WCF proxies are designed is to live until shi* happens. 
&lt;br&gt;
&lt;br&gt;
Let's assume that we have a CalcualtorService with one method named Divide(int a,
int b). Sasha, a&amp;nbsp;cool programmer-dude, trying to&amp;nbsp;produce some usefull software
writes:
&lt;/p&gt;
&lt;p&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;public&lt;/span&gt; MyCalcualtorForm
: Form {&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;private&lt;/span&gt; CalculatorProxy _calc &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;new&lt;/span&gt; CalculatorProxy();&lt;br&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;Calc_Click(...) {&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;_calc.Divide(firstNumber, secondNumber);&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br&gt;
}&lt;br&gt;
&lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
What is the&amp;nbsp;first error you can think of that could happen? Yep, DivideByZeroException.&lt;br&gt;
Once the proxy gets an exception, it enters into a "Faulted" state which makes the
proxy unusable(=you cannot use it again). 
&lt;br&gt;
The quickest solution is to work "by the book" and create a new instance each and
every time we need to call the service:
&lt;/p&gt;
&lt;p&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;Calc_Click(...)
{&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;using&lt;/span&gt; (CalculatorProxy
calc &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;new&lt;/span&gt; CalculatorProxy())&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;calc.Divide(firstNumber, secondNumber);&lt;br&gt;
}&lt;br&gt;
&lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
But what's bad in this solution?
&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
Performance - you pay (not a lot but neither little) for each creation of the proxy.
Sure, it will probably not be your bottleneck, but heck, why is it useful? Most of
the time the proxy will not throw an exception and yet we need to create it every
time just to avoid&amp;nbsp;the faulted state scenario.&amp;nbsp; 
&lt;li&gt;
Design - If we declare this exception BY CONTRACT, I would expect that the proxy will
still be usable afterwards. Do we really want to return Enum\int\string as status
instead of throwing exception just because of&amp;nbsp;poor design? 
&lt;li&gt;
TDD - you know that I'm in love with it. Now imagine Dependency Injection. Component
A recieve ICalculatorProxy and use it to... calculate something. Working "by the book"
is no good&amp;nbsp;as we want to recieve an instance of the proxy from the outside in
order to&amp;nbsp;mock it. Right,&amp;nbsp;so we inject a proxy from the outside (got to love
Windsor) and life is pretty sweeet. Darn! Wait!&amp;nbsp;one poor (even by design) exception
and our proxy goes dead. Very un-TDDish of Microsoft.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;
I had to come with&amp;nbsp;a solution&amp;nbsp;as no one will take TDD away from me. I present
to you ProtectedProxy: this&amp;nbsp;little IL-code-at-the-end-of-the-day&amp;nbsp;will able
you to recover from faulted state by creating a new proxy on each exception thus making
your proxy... useable (couldn't think about a better word to describe it). Think about
a situation where your proxy is trying to call the service but the service is down;&amp;nbsp;In
Semingo, we decided that we want to keep trying until the service is up. Via ProtectedProxy,
you can determine how many times do you want to recover and when you should finally
kill the proxy.&amp;nbsp;Oh yea, ProtectedProxy uses Windsor in order to create new proxies
if needed and logging messages to log4net. Good stuff.
&lt;/p&gt;
&lt;p&gt;
In the example above, all Sasha had to&amp;nbsp;do was to:&lt;br&gt;
1).&amp;nbsp;Initialize the _calc field by:&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;ProtectedProxy&amp;lt;ICalculatorProxy&amp;gt;
_calc = new ProtectedProxy&amp;lt;ICalculatorProxy&amp;gt;(new CalculatorProxy());&lt;br&gt;
2). call _calc via:&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; _calc.Instance.Divide(firstNumber, secondNumber);&lt;br&gt;
&lt;br&gt;
But enough said, code please:
&lt;/p&gt;
&lt;p&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&lt;span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;//
Written by Oren Ellenbogen (07.08.07) - trying to protect our proxies so they could
recover from:&lt;/span&gt;
&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;//
(A) The service is not up yet, but we want to try again later.&lt;/span&gt;
&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;//
(B) The service throws (ANY) exception, we still want our proxy to function (bubble
the exception, but still keep on working).&lt;/span&gt;
&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;//
Microsoft intended to use a NEW proxy per call, but for TDD this is not ideal as we
would like to inject proxies from outside as mocks&lt;/span&gt;
&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;//
in order to simulate multiple scenarios. &lt;/span&gt;
&lt;br&gt;
&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;#region&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;using&lt;/span&gt; 
&lt;br&gt;
&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;using&lt;/span&gt; System;&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;using&lt;/span&gt; System.Reflection;&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;using&lt;/span&gt; System.ServiceModel;&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;using&lt;/span&gt; Castle.Core.Resource;&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;using&lt;/span&gt; Castle.Windsor;&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;using&lt;/span&gt; Castle.Windsor.Configuration.Interpreters;&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;using&lt;/span&gt; log4net; 
&lt;br&gt;
&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;#endregion&lt;/span&gt; 
&lt;br&gt;
&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;namespace&lt;/span&gt; Semingo.Services.Proxies.Helpers&lt;br&gt;
{&lt;br&gt;
&lt;/span&gt;&lt;span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color=#0000ff&gt;public&lt;/font&gt; &lt;font color=#0000ff&gt;interface&lt;/font&gt; IProxy
: ICommunicationObject {&amp;nbsp;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color=#0000ff&gt;bool&lt;/font&gt; Ping();&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;/span&gt;
&lt;/p&gt;
&lt;div&gt;&lt;span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;///
&amp;lt;summary&amp;gt;&lt;/span&gt;
&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;///
Protect proxy from entering Faulted state by re-creating the proxy via Windsor Container
on Faulted.&lt;/span&gt;
&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;///
IMPORTANT: that even if a fatal exception is raised by the service (for example: the
service is not up yet), the proxy will be raised again.&amp;nbsp;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;/// Use it wisely (TIP: you CAN determine the number of 'recovery'
attempts).&lt;/span&gt;
&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;///
&amp;lt;/summary&amp;gt;&lt;/span&gt;
&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;///
&amp;lt;typeparam name="I"&amp;gt;The proxy interface to protect&amp;lt;/typeparam&amp;gt;&lt;/span&gt;
&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;///
&amp;lt;remarks&amp;gt;&lt;/span&gt;
&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;///
The way WCF works is that ANY exception on the service will cause the proxy to enter
"faulted" state which means you can not use it anymore.&lt;/span&gt;
&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;///
Imagine a service of CalculatorService that expose the method float Divide(int a,
int b). Sending b=0 will raise an exception in the service&lt;/span&gt;
&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;///
and the proxy will get into faulted state. This is not ideal as the proxy itself should
be used again.&lt;/span&gt;
&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;///
&amp;lt;/remarks&amp;gt;&lt;/span&gt;
&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;public&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;class&lt;/span&gt; ProtectedProxy&amp;lt;I&amp;gt;
: IDisposable&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;where I :&amp;nbsp;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&lt;font color=#000000&gt;IProxy&lt;/font&gt;&lt;/span&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;private&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;static&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;readonly&lt;/span&gt; ILog
_logger &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);&amp;nbsp;&lt;br&gt;
&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;private&lt;/span&gt; I
_instance;&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;private&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;readonly&lt;/span&gt; IWindsorContainer
_container;&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;private&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;int&lt;/span&gt; _faultedCounter &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; 0;&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;private&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;bool&lt;/span&gt; _disposed &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;false&lt;/span&gt;;&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;private&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;const&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;int&lt;/span&gt; AlertableNumberOfFaultedTimes &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; 10;&amp;nbsp;&lt;br&gt;
&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;public&lt;/span&gt; ProtectedProxy(I
instance)&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;: &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;this&lt;/span&gt;(CreateXmlBasedWindsorContainer(),
instance)&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&amp;nbsp;&lt;br&gt;
&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;public&lt;/span&gt; ProtectedProxy(IWindsorContainer
container, I instance)&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;_container &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; container;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;ShieldInstance(instance);&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&amp;nbsp;&lt;br&gt;
&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;///
&amp;lt;summary&amp;gt;&lt;/span&gt;
&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;///
Returns the number of faults this proxy had so far&lt;/span&gt;
&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;///
&amp;lt;/summary&amp;gt;&lt;/span&gt;
&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;public&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;int&lt;/span&gt; NumberOfFaults&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;get { &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;return&lt;/span&gt; _faultedCounter;
}&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&amp;nbsp;&lt;br&gt;
&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;public&lt;/span&gt; I
Instance&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;get&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;ThrowIfInstanceAlreadyDisposed();&amp;nbsp;&lt;br&gt;
&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&lt;/span&gt; (_instance.State
== CommunicationState.Faulted || _instance.State == CommunicationState.Closed || _instance.State
== CommunicationState.Closing)&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;_logger.Warn(&lt;span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4"&gt;"Notice:
The proxy state is invalid ("&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;+&lt;/span&gt; communicationObj.State &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;+&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4"&gt;").
The Faulted event should have been raised and handle this state - this need to be
checked."&lt;/span&gt;);&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;HandleFaultedInstance();&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br&gt;
&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&lt;/span&gt; _instance;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&amp;nbsp;&lt;br&gt;
&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;public&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;void&lt;/span&gt; Close()&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Dispose();&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&amp;nbsp;&lt;br&gt;
&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;private&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;void&lt;/span&gt; ThrowIfInstanceAlreadyDisposed()&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&lt;/span&gt; (_disposed)&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;throw&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;new&lt;/span&gt; ObjectDisposedException(&lt;span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4"&gt;"The
protected proxy for the type: "&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;+&lt;/span&gt; _instance.GetType().FullName &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;+&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4"&gt;"
was closed. Cannot return a live instance of this type."&lt;/span&gt;);&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&amp;nbsp;&lt;br&gt;
&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;private&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;void&lt;/span&gt; ShieldInstance(I
instance)&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;_instance &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; instance;&amp;nbsp;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;_instance.Faulted += &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;delegate&lt;/span&gt; {
HandleFaultedInstance(); };&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&amp;nbsp;&lt;br&gt;
&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;private&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;void&lt;/span&gt; HandleFaultedInstance()&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;ThrowIfInstanceAlreadyDisposed();&amp;nbsp;&lt;br&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;_faultedCounter++;&amp;nbsp;&lt;br&gt;
&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&lt;/span&gt; (_faultedCounter
&amp;gt;= AlertableNumberOfFaultedTimes)&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;_logger.Warn(&lt;span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4"&gt;"ALERT!
The proxy for the type "&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;+&lt;/span&gt; _instance.GetType().FullName &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;+&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4"&gt;"
got faulted for the "&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;+&lt;/span&gt; _faultedCounter &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;+&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4"&gt;"
time. Recreating the proxy but we must verify if this is valid."&lt;/span&gt;);&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;else&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;if&lt;/span&gt; (_logger.IsDebugEnabled)&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;_logger.Debug(&lt;span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4"&gt;"Proxy
for type "&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;+&lt;/span&gt; _instance.GetType().FullName &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;+&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4"&gt;"
got faulted (current state: "&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;+&lt;/span&gt; ((ICommunicationObject)_instance).State &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;+&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4"&gt;")
- recreating the proxy. Number of faulted instances so far: "&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;+&lt;/span&gt; _faultedCounter &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;+&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4"&gt;"."&lt;/span&gt;);&amp;nbsp;&lt;br&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;ProxyHelper.CloseProxy(_instance); &lt;span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;//
close current proxy&lt;/span&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;ShieldInstance(_container.Resolve&amp;lt;I&amp;gt;()); &lt;span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;//
re-create the proxy, faulted proxies are no good for further use.&lt;/span&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&amp;nbsp;&lt;br&gt;
&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;private&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;static&lt;/span&gt; IWindsorContainer
CreateXmlBasedWindsorContainer()&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;try&lt;/span&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;new&lt;/span&gt; WindsorContainer(&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;new&lt;/span&gt; XmlInterpreter(&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;new&lt;/span&gt; ConfigResource(&lt;span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4"&gt;"castle"&lt;/span&gt;)));&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;catch&lt;/span&gt; (Exception
err)&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;_logger.Warn(&lt;span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4"&gt;"Unable
to create xml based windsor container, using empty one."&lt;/span&gt;, err);&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;new&lt;/span&gt; WindsorContainer(); &lt;span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;//
for testing (the proxy will be mocked anyway).&lt;/span&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&amp;nbsp;&lt;br&gt;
&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;#region&lt;/span&gt; IDisposable
Members&amp;nbsp;&lt;br&gt;
&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;///&amp;lt;summary&amp;gt;&lt;/span&gt;
&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;///Performs
application-defined tasks associated with freeing, releasing, or resetting unmanaged
resources.&lt;/span&gt;
&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;///&amp;lt;/summary&amp;gt;&lt;/span&gt;
&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;public&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;void&lt;/span&gt; Dispose()&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Dispose(&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;true&lt;/span&gt;);&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;GC.SuppressFinalize(&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;this&lt;/span&gt;);&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&amp;nbsp;&lt;br&gt;
&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;protected&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;virtual&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;void&lt;/span&gt; Dispose(&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;bool&lt;/span&gt; disposing)&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;_logger.Info(&lt;span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4"&gt;"Attempting
to dispose the protected proxy for the type: "&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;+&lt;/span&gt; _instance.GetType().FullName &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;+&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4"&gt;",
disposed already? "&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;+&lt;/span&gt; _disposed);&amp;nbsp;&lt;br&gt;
&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&lt;/span&gt; (_disposed) &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;return&lt;/span&gt;;&amp;nbsp;&lt;br&gt;
&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&lt;/span&gt; (disposing)&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;ProxyHelper.CloseProxy(_instance);&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&amp;nbsp;&lt;br&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;_disposed &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;true&lt;/span&gt;;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&amp;nbsp;&lt;br&gt;
&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;#endregion&lt;/span&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br&gt;
&lt;br&gt;
&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;public&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;static&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;class&lt;/span&gt; ProxyHelper&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;private&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;static&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;readonly&lt;/span&gt; ILog
_logger &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);&amp;nbsp;&lt;br&gt;
&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;public&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;static&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;void&lt;/span&gt; CloseProxy(&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;object&lt;/span&gt; proxy)&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&lt;/span&gt; (proxy
== &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;null&lt;/span&gt;) &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;return&lt;/span&gt;;&amp;nbsp;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;CloseProxy(proxy &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;as&lt;/span&gt; ICommunicationObject);&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&amp;nbsp;&lt;br&gt;
&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;///
&amp;lt;summary&amp;gt;&lt;/span&gt;
&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;///
Close the proxy in a safe manner (will not throw exception)&lt;/span&gt;
&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;///
&amp;lt;/summary&amp;gt;&lt;/span&gt;
&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;///
&amp;lt;param name="proxy"&amp;gt;The proxy to close&amp;lt;/param&amp;gt;&lt;/span&gt;
&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;public&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;static&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;void&lt;/span&gt; CloseProxy(ICommunicationObject
proxy)&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&lt;/span&gt; (proxy
== &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;null&lt;/span&gt;) &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;return&lt;/span&gt;;&amp;nbsp;&lt;br&gt;
&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;try&lt;/span&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&lt;/span&gt; (proxy.State
== CommunicationState.Closing || proxy.State == CommunicationState.Closed || proxy.State
== CommunicationState.Faulted)&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;proxy.Abort();&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;else&lt;/span&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;proxy.Close();&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;catch&lt;/span&gt; (CommunicationException)&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;proxy.Abort();&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;catch&lt;/span&gt; (TimeoutException)&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;proxy.Abort();&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;catch&lt;/span&gt; (Exception
err)&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;_logger.Error(err);&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;proxy.Abort();&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;finally&lt;/span&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;proxy &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;null&lt;/span&gt;;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br&gt;
&lt;/span&gt;&lt;span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br&gt;
}&lt;/span&gt;&lt;span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;
&lt;br&gt;
&lt;/div&gt;
&gt; 
&lt;p&gt;
Hours of joy...
&lt;/p&gt;
&lt;p&gt;
Almost forgot, on the next post - "How to TDD WCF code" - stay tuned...
&lt;/p&gt;
&lt;img width="0" height="0" src="http://lnbogen.com/aggbug.ashx?id=76dbf68b-8dd6-4ebb-ab89-11a7b93f58d5" /&gt;</description>
      <comments>http://lnbogen.com/CommentView,guid,76dbf68b-8dd6-4ebb-ab89-11a7b93f58d5.aspx</comments>
      <category>.NET</category>
      <category>TDD</category>
      <category>WCF</category>
    </item>
    <item>
      <trackback:ping>http://lnbogen.com/Trackback.aspx?guid=e802c6ec-cc1b-4c21-8e17-c7b802772e85</trackback:ping>
      <pingback:server>http://lnbogen.com/pingback.aspx</pingback:server>
      <pingback:target>http://lnbogen.com/PermaLink,guid,e802c6ec-cc1b-4c21-8e17-c7b802772e85.aspx</pingback:target>
      <dc:creator>Oren Ellenbogen</dc:creator>
      <wfw:comment>http://lnbogen.com/CommentView,guid,e802c6ec-cc1b-4c21-8e17-c7b802772e85.aspx</wfw:comment>
      <wfw:commentRss>http://lnbogen.com/SyndicationService.asmx/GetEntryCommentsRss?guid=e802c6ec-cc1b-4c21-8e17-c7b802772e85</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
One of the most common question in moving towards Agile Development is <strong>"</strong>Where
should I start from?<strong>"</strong>. If you'll ask me, setup a Continuous Integration
(aka "CC") would be the first thing you should start with.
</p>
        <p>
          <strong>
            <u>Step 1 (Check for compilation bugs): Code Quality ~= 30%</u>
          </strong>
        </p>
        <p>
The CC should be able to identify check-ins to your source control, get the latest
source and compile it. The output should be either "green" (Everything compiles successfully
with 0 warnings) or "red" (more than one warning or compilation errors). In addition
to the fast feedback, the output should also include the files that were changed from
the last build (and by whom, so people could know where to look).
</p>
        <p>
The immediate value is priceless. the ability to SEE whether your source-code
is stable enough to allow other programmers perform Get Latest and continue their
work and the "fail-fast" attitude can save you a lot of time in the long run. It's
important to realize though that even if the code compiles without warnings,
it still doesn't mean that you could count on the quality of the code.
</p>
        <p>
          <strong>
            <u>Step 2 (Check for component-based quality): Code Quality ~= 70%<a href="http://www.lnbogen.com/content/binary/CC.jpg" atomicselection="true"><img style="BORDER-TOP-WIDTH: 0px; BORDER-LEFT-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; BORDER-RIGHT-WIDTH: 0px" height="95" src="http://www.lnbogen.com/content/binary/CC.jpg" width="124" align="right" border="0" /></a></u>
          </strong>
        </p>
        <p>
If you can go one extra mile, write a few automated tests (via one of the available
XUnit frameworks) for your components. This means that you are able to inject
the component's dependencies from the outside and simulate mini use-cases on component's
level. This step is crucial even if you write those after the code
itself was written. Let the CC run them if Step 1 is OK. This should allow
you to catch the majority of your bugs (I'll leave the "how to write good
tests" to another post). If all is green, you know that the system behaves as expected,
at least to some extent.
</p>
        <p>
This step is not trivial as it requires you to design for testability and invest in
proper testing. Don't let go of this step though, automated tests on this
level will make your life much easier. It will take your code one (major) step
ahead in "write code that could be changed". Agile is all about that state of mind.
</p>
        <p>
          <strong>
            <u>Step 3 (Check for integration-based quality): Code Quality ~= 80% </u>
          </strong>
        </p>
        <p>
          <a href="http://www.lnbogen.com/content/binary/FailingCC.jpg" atomicselection="true">
            <img style="BORDER-TOP-WIDTH: 0px; BORDER-LEFT-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; BORDER-RIGHT-WIDTH: 0px" height="330" src="http://www.lnbogen.com/content/binary/FailingCC.jpg" width="406" align="right" border="0" />
          </a>
        </p>
        <p>
Now that you're components are behaving as expected, you should try to write
a few (automated, of course) tests that simulate the entire flow of 2 or more
components (DB is a component as well) in the system. As the system
grows and more uses cases are added, you should try to improve these tests as they
give a solid proof that the SYSTEM works.
</p>
        <p>
          <strong>
            <u>Step 4 (Make everything visible): Code Quality ~= 90%</u>
          </strong>
        </p>
        <p>
The state &amp; quality of your source control should be visible to the Team and Management
as you want to insure IMMEDIATE response time in case someone check-ins
a low quality code (on any level). Fixing a failing test three days after the
change itself is a bad symptom of low visibility or low perception, by the Team, regarding
the importance of the quality of the system.
</p>
        <p>
          <strong>
            <u>Step 5 (Automated deployment): Code Quality ~= 95%</u>
          </strong>
        </p>
        <p>
After successful build you would like to deploy the latest source on a dedicated environment
which the developers could play with before deploying to another (testing?) environment.
This won't be a stable environment, but at least it will give a quick look at the
current state of the system - the way customers would see it.
</p>
        <p>
          <strong>
            <u>Step 6 (Procedures checking): Code Quality &gt; 95%:</u>
          </strong>
        </p>
        <p>
You can add many more checks to the flow, such as Tests Coverage or FxCop. Leave
those to the end. From my experience, Time .vs. Value in these features will vary
from team to team. You'll gain much more from investing in Steps 2-3.
</p>
        <p>
 
</p>
        <h2>
          <strong>
            <u>Semingo CC:</u>
          </strong>
        </h2>
        <p>
Each developer &amp; manager on our team have a CCTray(the little red circle
in the little picture above) which is either Red(source control is damaged),
Yellow(Build in action) or Green(Life is sweet). We're using Cruise Control.Net, CCTray,
MSBuild (and TFS plugin) and NUnit to perform all of the above. 
</p>
        <p>
A few teasers:
</p>
        <p>
* Image of Steve Urkel (from the famous Family Matters TV series) is shown for failing
build.
</p>
        <p>
* <a href="http://www.lnbogen.com/content/binary/GoodCC.jpg" atomicselection="true"><img style="BORDER-TOP-WIDTH: 0px; BORDER-LEFT-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; BORDER-RIGHT-WIDTH: 0px" height="215" src="http://www.lnbogen.com/content/binary/GoodCC.jpg" width="530" align="right" border="0" /></a>On
the right you can find <a href="http://www.pashabitz.com/">Pasha</a> (with a V sign
I've added), one of our finest hackers modeling a successful build. You
can also notice the 582 green tests (including Integration tests) and 2 changes
made by Sagie since the last build.
</p>
        <p>
* Going to NUnit Details, you can get the full details:<br /><br /><a href="http://www.lnbogen.com/content/binary/UnitTestsCC.jpg" atomicselection="true"><img style="BORDER-TOP-WIDTH: 0px; BORDER-LEFT-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; BORDER-RIGHT-WIDTH: 0px" height="140" src="http://www.lnbogen.com/content/binary/UnitTestsCC.jpg" width="465" border="0" /></a></p>
        <p>
 
</p>
        <p>
I had to cut the pictures in order to keep a sane width for the post, but you can
get the drift.
</p>
        <p>
btw - Aviel, yet another Semingo hacker add a "Doh!" (Simpson) each time the
CC is red on his computer. It can be quite funny (and scary, if fully concentrated
on code).
</p>
        <img width="0" height="0" src="http://lnbogen.com/aggbug.ashx?id=e802c6ec-cc1b-4c21-8e17-c7b802772e85" />
      </body>
      <title>Continuous Integration as Quality Reflection</title>
      <guid isPermaLink="false">http://lnbogen.com/PermaLink,guid,e802c6ec-cc1b-4c21-8e17-c7b802772e85.aspx</guid>
      <link>http://lnbogen.com/2007/09/03/ContinuousIntegrationAsQualityReflection.aspx</link>
      <pubDate>Mon, 03 Sep 2007 12:42:23 GMT</pubDate>
      <description>&lt;p&gt;
One of the most common question in moving towards Agile Development is &lt;strong&gt;"&lt;/strong&gt;Where
should I start from?&lt;strong&gt;"&lt;/strong&gt;. If you'll ask me, setup a Continuous Integration
(aka "CC") would be the first thing you should start with.
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;&lt;u&gt;Step 1 (Check for compilation bugs): Code Quality ~= 30%&lt;/u&gt;&lt;/strong&gt;
&lt;/p&gt;
&lt;p&gt;
The CC should be able to identify check-ins&amp;nbsp;to your source control, get the latest
source and compile it. The output should be either "green" (Everything compiles successfully
with 0 warnings) or "red" (more than one warning or compilation errors). In addition
to the fast feedback, the output should also include the files that were changed from
the last build&amp;nbsp;(and by whom, so people could know where to look).
&lt;/p&gt;
&lt;p&gt;
The immediate value is priceless. the ability to&amp;nbsp;SEE whether your source-code
is stable enough to allow other programmers perform Get Latest and continue their
work and the "fail-fast" attitude can save you a lot of time in the long run.&amp;nbsp;It's
important to realize though that even if&amp;nbsp;the code compiles without warnings,
it still doesn't mean that&amp;nbsp;you could count on the quality of the code.
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;&lt;u&gt;Step 2 (Check for&amp;nbsp;component-based quality): Code Quality&amp;nbsp;~= 70%&lt;a href="http://www.lnbogen.com/content/binary/CC.jpg" atomicselection="true"&gt;&lt;img style="BORDER-TOP-WIDTH: 0px; BORDER-LEFT-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; BORDER-RIGHT-WIDTH: 0px" height=95 src="http://www.lnbogen.com/content/binary/CC.jpg" width=124 align=right border=0&gt;&lt;/a&gt;&lt;/u&gt;&lt;/strong&gt;
&lt;/p&gt;
&lt;p&gt;
If you can go one extra mile, write a few automated tests (via one of the available
XUnit frameworks) for your components. This means that you&amp;nbsp;are able to inject
the component's dependencies from the outside and simulate mini use-cases on component's
level.&amp;nbsp;This step is crucial even if&amp;nbsp;you write those&amp;nbsp;after the code
itself was written.&amp;nbsp;Let the CC run them if Step 1&amp;nbsp;is OK. This should allow
you to catch the&amp;nbsp;majority of your&amp;nbsp;bugs (I'll leave the "how to write good
tests" to another post). If all is green, you know that the system behaves as expected,
at least to some extent.
&lt;/p&gt;
&lt;p&gt;
This step is not trivial as it requires you to design for testability and invest in
proper testing. Don't let go of this step though,&amp;nbsp;automated tests&amp;nbsp;on this
level will make your life much easier. It will&amp;nbsp;take your code one (major)&amp;nbsp;step
ahead in "write code that could be changed". Agile is all about that state of mind.
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;&lt;u&gt;Step 3 (Check for integration-based quality): Code Quality&amp;nbsp;~= 80% &lt;/u&gt;&lt;/strong&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://www.lnbogen.com/content/binary/FailingCC.jpg" atomicselection="true"&gt;&lt;img style="BORDER-TOP-WIDTH: 0px; BORDER-LEFT-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; BORDER-RIGHT-WIDTH: 0px" height=330 src="http://www.lnbogen.com/content/binary/FailingCC.jpg" width=406 align=right border=0&gt;&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;
Now that you're components are behaving as expected, you should&amp;nbsp;try&amp;nbsp;to&amp;nbsp;write
a few (automated, of course) tests that&amp;nbsp;simulate the entire flow of 2 or more
components (DB&amp;nbsp;is a&amp;nbsp;component as well)&amp;nbsp;in the system. As the system
grows and more uses cases are added, you should try to improve these tests as they
give a solid proof that the SYSTEM works.
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;&lt;u&gt;Step 4 (Make everything visible): Code Quality&amp;nbsp;~= 90%&lt;/u&gt;&lt;/strong&gt;
&lt;/p&gt;
&lt;p&gt;
The state &amp;amp; quality of your source control should be visible to the Team and Management
as you want to insure&amp;nbsp;IMMEDIATE&amp;nbsp;response time in case someone check-ins
a low quality code (on any level). Fixing a failing test&amp;nbsp;three days after the
change itself is a bad symptom of low visibility or low perception, by the Team,&amp;nbsp;regarding
the importance of the quality of the system.
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;&lt;u&gt;Step 5 (Automated deployment): Code Quality&amp;nbsp;~= 95%&lt;/u&gt;&lt;/strong&gt;
&lt;/p&gt;
&lt;p&gt;
After successful build you would like to deploy the latest source on a dedicated environment
which the developers could play with before deploying to another (testing?) environment.
This won't be a stable environment, but at least it will give a quick look at the
current state of the system - the way customers would see it.
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;&lt;u&gt;Step&amp;nbsp;6 (Procedures checking): Code Quality &amp;gt; 95%:&lt;/u&gt;&lt;/strong&gt;
&lt;/p&gt;
&lt;p&gt;
You can add many more checks to the flow, such as Tests Coverage or&amp;nbsp;FxCop. Leave
those to the end. From my experience, Time .vs. Value in these features will vary
from team to team. You'll gain much more from investing in Steps 2-3.
&lt;/p&gt;
&lt;p&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;h2&gt;&lt;strong&gt;&lt;u&gt;Semingo CC:&lt;/u&gt;&lt;/strong&gt;
&lt;/h2&gt;
&lt;p&gt;
Each&amp;nbsp;developer &amp;amp; manager on our&amp;nbsp;team have a CCTray(the little red circle
in the little picture above)&amp;nbsp;which is either Red(source control is damaged),
Yellow(Build in action) or Green(Life is sweet). We're using Cruise Control.Net, CCTray,
MSBuild (and TFS plugin) and NUnit to perform all of the above.&amp;nbsp;
&lt;/p&gt;
&lt;p&gt;
A few teasers:
&lt;/p&gt;
&lt;p&gt;
* Image of Steve Urkel (from the famous Family Matters TV series) is shown for failing
build.
&lt;/p&gt;
&lt;p&gt;
* &lt;a href="http://www.lnbogen.com/content/binary/GoodCC.jpg" atomicselection="true"&gt;&lt;img style="BORDER-TOP-WIDTH: 0px; BORDER-LEFT-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; BORDER-RIGHT-WIDTH: 0px" height=215 src="http://www.lnbogen.com/content/binary/GoodCC.jpg" width=530 align=right border=0&gt;&lt;/a&gt;On
the right you can find &lt;a href="http://www.pashabitz.com/"&gt;Pasha&lt;/a&gt; (with a V sign
I've added), one of our finest hackers modeling&amp;nbsp;a successful&amp;nbsp;build. You
can also notice the 582 green tests (including Integration tests) and&amp;nbsp;2 changes
made by Sagie since the last build.
&lt;/p&gt;
&lt;p&gt;
* Going to NUnit Details, you can get the full details:&lt;br&gt;
&lt;br&gt;
&lt;a href="http://www.lnbogen.com/content/binary/UnitTestsCC.jpg" atomicselection="true"&gt;&lt;img style="BORDER-TOP-WIDTH: 0px; BORDER-LEFT-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; BORDER-RIGHT-WIDTH: 0px" height=140 src="http://www.lnbogen.com/content/binary/UnitTestsCC.jpg" width=465 border=0&gt;&lt;/a&gt; 
&lt;/p&gt;
&lt;p&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p&gt;
I had to cut the pictures in order to keep a sane width for the post, but you can
get the drift.
&lt;/p&gt;
&lt;p&gt;
btw -&amp;nbsp;Aviel, yet another Semingo hacker add a "Doh!" (Simpson) each time the
CC is red on his computer. It can be quite funny (and scary, if fully concentrated
on code).
&lt;/p&gt;
&lt;img width="0" height="0" src="http://lnbogen.com/aggbug.ashx?id=e802c6ec-cc1b-4c21-8e17-c7b802772e85" /&gt;</description>
      <comments>http://lnbogen.com/CommentView,guid,e802c6ec-cc1b-4c21-8e17-c7b802772e85.aspx</comments>
      <category>Agile</category>
      <category>Management</category>
    </item>
    <item>
      <trackback:ping>http://lnbogen.com/Trackback.aspx?guid=2c70c358-1410-46b0-9b57-f8a39aeb0fe2</trackback:ping>
      <pingback:server>http://lnbogen.com/pingback.aspx</pingback:server>
      <pingback:target>http://lnbogen.com/PermaLink,guid,2c70c358-1410-46b0-9b57-f8a39aeb0fe2.aspx</pingback:target>
      <dc:creator>Oren Ellenbogen</dc:creator>
      <wfw:comment>http://lnbogen.com/CommentView,guid,2c70c358-1410-46b0-9b57-f8a39aeb0fe2.aspx</wfw:comment>
      <wfw:commentRss>http://lnbogen.com/SyndicationService.asmx/GetEntryCommentsRss?guid=2c70c358-1410-46b0-9b57-f8a39aeb0fe2</wfw:commentRss>
      <slash:comments>1</slash:comments>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
A few pearls from the office:
</p>
        <ul>
          <li>
            <a href="http://www.pashabitz.com/">Pasha</a>: Damn, I like TDD so much. Writing a
5 minutes piece of code takes about a day (sarcastic tone, of course).<br /></li>
          <li>
Aviel: in my case, code does not come from my head but rather from my heart.<br /><a href="http://www.pashabitz.com/">Pasha</a>: I saw your code. It comes from your
ass.<br /></li>
          <li>
Me: Integration environment is the Tamagochi of an Agile Team<br /></li>
          <li>
(Phone ringing, Pasha answers) 
<br />
Robert: I'm Robert. 
<br /><a href="http://www.pashabitz.com/">Pasha</a>: I'm Robert. 
<br />
Robert: I'm Robert. 
<br /><a href="http://www.pashabitz.com/">Pasha</a>: I'm not Robert, I'm Pasha. 
<br />
Robert: Oh, My bad. 
<br /><a href="http://www.pashabitz.com/">Pasha</a>: Bye then. 
<br />
(end of conversation).</li>
        </ul>
        <img width="0" height="0" src="http://lnbogen.com/aggbug.ashx?id=2c70c358-1410-46b0-9b57-f8a39aeb0fe2" />
      </body>
      <title>Another day at the office</title>
      <guid isPermaLink="false">http://lnbogen.com/PermaLink,guid,2c70c358-1410-46b0-9b57-f8a39aeb0fe2.aspx</guid>
      <link>http://lnbogen.com/2007/07/26/AnotherDayAtTheOffice.aspx</link>
      <pubDate>Thu, 26 Jul 2007 17:32:25 GMT</pubDate>
      <description>&lt;p&gt;
A&amp;nbsp;few pearls from the office:
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;a href="http://www.pashabitz.com/"&gt;Pasha&lt;/a&gt;: Damn, I like TDD so much. Writing a
5 minutes piece of code takes about a day (sarcastic tone, of course).&lt;br&gt;
&lt;li&gt;
Aviel: in my case, code&amp;nbsp;does not come from my&amp;nbsp;head but rather from my heart.&lt;br&gt;
&lt;a href="http://www.pashabitz.com/"&gt;Pasha&lt;/a&gt;: I saw your code. It comes from your
ass.&lt;br&gt;
&lt;li&gt;
Me: Integration&amp;nbsp;environment is the Tamagochi of an Agile Team&lt;br&gt;
&lt;li&gt;
(Phone ringing, Pasha answers) 
&lt;br&gt;
Robert: I'm Robert. 
&lt;br&gt;
&lt;a href="http://www.pashabitz.com/"&gt;Pasha&lt;/a&gt;: I'm Robert. 
&lt;br&gt;
Robert: I'm Robert. 
&lt;br&gt;
&lt;a href="http://www.pashabitz.com/"&gt;Pasha&lt;/a&gt;: I'm not Robert, I'm Pasha. 
&lt;br&gt;
Robert: Oh, My bad. 
&lt;br&gt;
&lt;a href="http://www.pashabitz.com/"&gt;Pasha&lt;/a&gt;: Bye then. 
&lt;br&gt;
(end of conversation).&lt;/li&gt;
&lt;/ul&gt;
&lt;img width="0" height="0" src="http://lnbogen.com/aggbug.ashx?id=2c70c358-1410-46b0-9b57-f8a39aeb0fe2" /&gt;</description>
      <comments>http://lnbogen.com/CommentView,guid,2c70c358-1410-46b0-9b57-f8a39aeb0fe2.aspx</comments>
      <category>@ff Topic</category>
    </item>
    <item>
      <trackback:ping>http://lnbogen.com/Trackback.aspx?guid=e6060063-54a8-44cb-ba97-5d9a83446011</trackback:ping>
      <pingback:server>http://lnbogen.com/pingback.aspx</pingback:server>
      <pingback:target>http://lnbogen.com/PermaLink,guid,e6060063-54a8-44cb-ba97-5d9a83446011.aspx</pingback:target>
      <dc:creator>Oren Ellenbogen</dc:creator>
      <wfw:comment>http://lnbogen.com/CommentView,guid,e6060063-54a8-44cb-ba97-5d9a83446011.aspx</wfw:comment>
      <wfw:commentRss>http://lnbogen.com/SyndicationService.asmx/GetEntryCommentsRss?guid=e6060063-54a8-44cb-ba97-5d9a83446011</wfw:commentRss>
      <slash:comments>8</slash:comments>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
After almost 1.5 months of Scrum at Semingo (a baby startup), I decided to expose
the way we work at the moment and talk about the adjustments we've made in order to
suit Scrum to our needs.
</p>
        <p>
I'll start with our implementation to the Daily Stand-up Meeting. No doubt,
our meetings are pretty funny (most of the time) and create the right vibe for the
Team. The one thing I love most about our meetings is that by the end of the meeting,
I know what is the general work-plan for each member in my Team. 
<br /><br />
Now it's easy to know what I'm planning to complete today (I spend 5-10 minutes
planning my day before the meeting), when &amp; if I need to finish something
earlier (or at least decide about interfaces after the meeting) in order to integrate
with others, help out or ask for someone's else help(code review for example), stay
after the meeting in order to talk about something that pop up during the meeting,
remove impediments (if I can) and most importantly - have a good laugh before
the day begins.
</p>
        <p>
          <strong>
            <font size="3">Daily Stand-up Meeting (aka DSM) structure at Semingo:</font>
          </strong>
        </p>
        <p>
          <strong>When:</strong> <br />
Every day at 10:30. 
<br /><strong>Where:</strong><br />
Meetings room.<br /><strong>Time Box:</strong><br />
15 minutes.<br /><strong>Attendants:</strong> <br />
Pigs only (Chickens can (only) listen)<br /><strong>On the table: <br /></strong>Each Pig answer these 4(!) questions:<br />
(1) What have I done since the last DSM ?<br />
(2) What am I planning to do until the next DSM ?<br />
(3) Impediments - what bothers me to work ?<br />
(4) Am I on track?<br />
     If someone feels that one of his tasks won't be finished
as planned, a flag is raised so the Team could assist. <br />
     The same goes if someone feels that he's going
to finish before the expected time. <br />
     This means that he could help out someone else or take a
few extra tasks we did not plan for the current iteration.<br /><strong><br />
Notes:<br /></strong>Only one Pig talks at a time and he leads the conversation if reasonable
questions comes up. He (alone) has the power to stop a conversation if he
feels the conversation stray from the DSM path. Team members can decide to talk about
an issue that was raised during the DSM just after the meeting is finished.
</p>
        <p>
          <strong>What next (DSM planned improvements)?</strong>
          <br />
(1) You late, you get (punished, that is): each team member that late to the DSM must
wear the "I was late to DSM, I will serve you coffee today" sign on his
shirt.<br />
(2) Red-Back on track: If the conversation is getting out of control (too many jokes,
drill-down conversations, more than 1 Pig talk etc) - the red button is clicked and
each Team member is being electrified with 120V. Well no, but it could have been a
nice feature right? Clicking the red button will make a nice GONG!! so we could move
on. The Team agree to listen to the GONG and get back on track, so we could finish
in time and keeping the DSM productive.
</p>
        <img width="0" height="0" src="http://lnbogen.com/aggbug.ashx?id=e6060063-54a8-44cb-ba97-5d9a83446011" />
      </body>
      <title>Semicrum - Implementing Scrum at Semingo</title>
      <guid isPermaLink="false">http://lnbogen.com/PermaLink,guid,e6060063-54a8-44cb-ba97-5d9a83446011.aspx</guid>
      <link>http://lnbogen.com/2007/07/14/SemicrumImplementingScrumAtSemingo.aspx</link>
      <pubDate>Sat, 14 Jul 2007 15:51:27 GMT</pubDate>
      <description>&lt;p&gt;
After almost 1.5 months of Scrum at Semingo (a baby startup), I decided to expose
the way we work at the moment and talk about the adjustments we've made in order to
suit Scrum&amp;nbsp;to our needs.
&lt;/p&gt;
&lt;p&gt;
I'll start with our implementation&amp;nbsp;to the&amp;nbsp;Daily Stand-up Meeting. No doubt,
our meetings&amp;nbsp;are pretty funny (most of the time) and create the right vibe for&amp;nbsp;the
Team. The one thing I love most about our meetings is that by the end of the meeting,
I know what is the general work-plan for each member in my Team. 
&lt;br&gt;
&lt;br&gt;
Now it's easy to know what I'm planning to&amp;nbsp;complete today (I spend 5-10 minutes
planning my day before the meeting), when &amp;amp; if&amp;nbsp;I need to finish something
earlier (or&amp;nbsp;at least decide about interfaces after the meeting) in order to integrate
with others, help out or ask for someone's else help(code review for example), stay
after the meeting in order to talk about something that pop up during the meeting,
remove impediments (if I can) and most importantly&amp;nbsp;- have a good laugh before
the day begins.
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;&lt;font size=3&gt;Daily Stand-up Meeting (aka DSM) structure at Semingo:&lt;/font&gt;&lt;/strong&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;When:&lt;/strong&gt;&amp;nbsp;&lt;br&gt;
Every day at 10:30. 
&lt;br&gt;
&lt;strong&gt;Where:&lt;/strong&gt;
&lt;br&gt;
Meetings room.&lt;br&gt;
&lt;strong&gt;Time Box:&lt;/strong&gt;
&lt;br&gt;
15 minutes.&lt;br&gt;
&lt;strong&gt;Attendants:&lt;/strong&gt;&amp;nbsp;&lt;br&gt;
Pigs only (Chickens can (only) listen)&lt;br&gt;
&lt;strong&gt;On the table:&amp;nbsp;&lt;br&gt;
&lt;/strong&gt;Each Pig answer these 4(!) questions:&lt;br&gt;
(1) What have I done since the last DSM ?&lt;br&gt;
(2) What am I planning to do until the next DSM ?&lt;br&gt;
(3) Impediments -&amp;nbsp;what bothers me to work ?&lt;br&gt;
(4)&amp;nbsp;Am I on track?&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;If someone feels that one of his tasks won't be finished
as planned, a flag is raised so the Team could assist.&amp;nbsp;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;The same goes if someone feels that he's&amp;nbsp;going
to finish before the expected time.&amp;nbsp;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; This means that he could help out someone else or take a
few extra tasks we did not plan for the current iteration.&lt;br&gt;
&lt;strong&gt;
&lt;br&gt;
Notes:&lt;br&gt;
&lt;/strong&gt;Only one Pig talks at a time and he&amp;nbsp;leads the conversation if reasonable
questions comes up. He&amp;nbsp;(alone) has the power&amp;nbsp;to stop a conversation if he
feels the conversation stray from the DSM path. Team members can decide to talk about
an issue that was raised during the DSM just after the&amp;nbsp;meeting is&amp;nbsp;finished.
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;What next (DSM planned improvements)?&lt;/strong&gt;
&lt;br&gt;
(1) You late, you get (punished, that is): each team member that late to the DSM must
wear the "I was late to DSM,&amp;nbsp;I will serve you&amp;nbsp;coffee today" sign on&amp;nbsp;his
shirt.&lt;br&gt;
(2) Red-Back on track: If the conversation is getting out of control (too many jokes,
drill-down conversations, more than 1 Pig talk etc) - the red button is clicked and
each Team member is being electrified with 120V. Well no, but it could have been a
nice feature right? Clicking the red button will make a nice GONG!! so we could move
on. The Team agree to listen to the GONG and get back on track, so we could finish
in time and keeping the DSM productive.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://lnbogen.com/aggbug.ashx?id=e6060063-54a8-44cb-ba97-5d9a83446011" /&gt;</description>
      <comments>http://lnbogen.com/CommentView,guid,e6060063-54a8-44cb-ba97-5d9a83446011.aspx</comments>
      <category>Agile</category>
      <category>Scrum</category>
    </item>
    <item>
      <trackback:ping>http://lnbogen.com/Trackback.aspx?guid=055de749-53f4-4fe4-b223-9b77ca49a280</trackback:ping>
      <pingback:server>http://lnbogen.com/pingback.aspx</pingback:server>
      <pingback:target>http://lnbogen.com/PermaLink,guid,055de749-53f4-4fe4-b223-9b77ca49a280.aspx</pingback:target>
      <dc:creator>Oren Ellenbogen</dc:creator>
      <wfw:comment>http://lnbogen.com/CommentView,guid,055de749-53f4-4fe4-b223-9b77ca49a280.aspx</wfw:comment>
      <wfw:commentRss>http://lnbogen.com/SyndicationService.asmx/GetEntryCommentsRss?guid=055de749-53f4-4fe4-b223-9b77ca49a280</wfw:commentRss>
      <slash:comments>5</slash:comments>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
Gosh, I did not know <a href="http://codebetter.com/blogs/raymond.lewallen/default.aspx">Raymond
Lewallen</a> was reading my blog (I guess I should start writing some meaningful stuff
and stop playing around ;)) but I'm more than happy to raise up to <a href="http://codebetter.com/blogs/raymond.lewallen/archive/2007/07/11/what-i-am-doing-to-become-a-better-developer.aspx">the
challenge</a> and talk about what I am doing in order to go to the next level.
</p>
        <p>
In one of my post, <a href="http://www.lnbogen.com/WhatItTakesToBecomeAGreatDeveloper.aspx">What
it takes to become a great developer</a>, I mentioned the notion of "Be Eager To Learn".
I don't consider myself as a good developer due to my natural skills (I don't
think that I'm mediocre, but certainly not Larry Page). Starting 8 years ago
as a little teenager at 15, I had to work my ass off in order to keep up and show
the rest of the people I was working with that I'm just as good as they are. Reaching
this goal, I wanted to show myself that I can be the best guy at the company. 
</p>
        <p>
Eight years passed and a lot have changed, but I'm still very much eager to get better
and more versatile. One thing I'll always keep with me, as it proved it self
so far, is the no-fear attitude and the (sometimes) ridiculous optimism. I'm
not afraid of doing new things or changing positions when an "offer you can't refuse"
knocks on my door. Life is short and you most grow each and every day. I'm still the
same team player guy, although I can get over confident (aka arrogant) or raise my
voice here and there. I care about my teammates and know when to say "I'm sorry".
I work with my heart and hopefully my current and future teammates will forgive me
for my faults.
</p>
        <p>
I think that in the last few years I've learned a lot about myself, about the things
that really intrigued me, that push me to excel. I love coding, I love talking with
people, mentoring, lecturing about technologies or Agile methodologies, but most
of all - I enjoy taking ownership of projects I participate in and making
them successful. I'm looking to surround myself with people smarter than me,
those that have natural gifts in them, and making them better.
</p>
        <p>
          <strong>Things I should do</strong>
        </p>
        <p>
I should try to get more organized in planning my time. I read a lot of books about
self management but I don't feel like I'm practicing them as much as I should. I should
really invest more time in myself, trying to set goals and constantly reviewing them.
I'm leading the Agile a la Scrum at Semingo so I hope to use this work &amp; review notion
more in my life.
</p>
        <p>
I should learn more about Agile, Scrum and XP. I've read a few great books
about Agile\Scrum\Management but I still have a lot of unanswered questions. I know
that these methodologies only offer some solutions but I don't believe we should enforce
them. I believe in making our own Agile process at Semingo. That said, I do want
to read more books from people with different experience, different ideas and best
practices I could learn from.
</p>
        <p>
I should definitely write more posts! (particularly about Agile\Scrum)
</p>
        <p>
          <strong>Things I want to do</strong>
        </p>
        <p>
TDD: getting better in it and start lecturing about it more.<br />
Multi-threading: This one is a new set of skills I'm developing at my current job.
Looking at the near future, this skill is crucial as a developer.<br />
WCF: I need to use it in my current job and I have a lot of catch up to do.<br />
Lecturing: At least 4-5 lectures a year looks like a solid goal at the moment.<br /><br />
Most of all, I want to make Semingo the best place to work at, to bring more amazing
guys&amp;gals to work with us and making an application that will change the way millions
of people work.<br /><strong><br />
Things I won't do</strong></p>
        <p>
I think that it's getting clear to me that I do not want to be an external coach.
I don't see myself coaching a team for a 2-3 months and then shifting to another team.
I enjoy working with people and I take pride and strength in making things complete.
</p>
        <p>
I won't stop talking and writing about software, practices and people as long as I
have keyboard and working set of 1-N fingers available. Count on it!
</p>
        <p>
          <strong>
            <br />
Tagging these folks</strong>
        </p>
        <p>
          <a href="http://www.pashabitz.com/">Pasha Bitz</a>, <a href="http://www.human-debugger.net/">Shani
Raba</a>, <a href="http://doronsharp.spaces.live.com/">Doron Yaacoby</a>, <a href="http://www.eranachum.com/">Eran
Nachum</a>, <a href="http://www.kenegozi.com/blog/">Ken Egozi</a></p>
        <img width="0" height="0" src="http://lnbogen.com/aggbug.ashx?id=055de749-53f4-4fe4-b223-9b77ca49a280" />
      </body>
      <title>What I am doing to become a better developer</title>
      <guid isPermaLink="false">http://lnbogen.com/PermaLink,guid,055de749-53f4-4fe4-b223-9b77ca49a280.aspx</guid>
      <link>http://lnbogen.com/2007/07/13/WhatIAmDoingToBecomeABetterDeveloper.aspx</link>
      <pubDate>Fri, 13 Jul 2007 18:52:36 GMT</pubDate>
      <description>&lt;p&gt;
Gosh, I did not know &lt;a href="http://codebetter.com/blogs/raymond.lewallen/default.aspx"&gt;Raymond
Lewallen&lt;/a&gt; was reading my blog (I guess I should start writing some meaningful stuff
and stop playing around ;)) but I'm more than happy to raise up to &lt;a href="http://codebetter.com/blogs/raymond.lewallen/archive/2007/07/11/what-i-am-doing-to-become-a-better-developer.aspx"&gt;the
challenge&lt;/a&gt; and talk about what I am&amp;nbsp;doing in order to go to the next level.
&lt;/p&gt;
&lt;p&gt;
In one of my post,&amp;nbsp;&lt;a href="http://www.lnbogen.com/WhatItTakesToBecomeAGreatDeveloper.aspx"&gt;What
it takes to become a great developer&lt;/a&gt;, I mentioned the notion of "Be Eager To Learn".
I don't consider myself as a good&amp;nbsp;developer due to my natural skills (I don't
think that I'm&amp;nbsp;mediocre, but certainly not Larry Page). Starting 8 years ago
as a little teenager at 15, I had to work my ass off in order to keep up and show
the rest of the people I was working with that I'm just as good as they are. Reaching
this goal, I wanted to show myself that I can be the best guy at the company. 
&lt;/p&gt;
&lt;p&gt;
Eight years passed and a lot have changed, but I'm still very much eager to get better
and more versatile.&amp;nbsp;One thing I'll always keep with me, as it proved it self
so far, is&amp;nbsp;the no-fear attitude and the (sometimes) ridiculous optimism. I'm
not afraid of doing new things or changing positions when an "offer you can't refuse"
knocks on my door. Life is short and you most grow each and every day. I'm still the
same team player guy, although I can get over confident (aka arrogant) or raise my
voice here and there. I care about my teammates and know when to say "I'm sorry".
I work with my heart and hopefully my current and future teammates will forgive me
for my faults.
&lt;/p&gt;
&lt;p&gt;
I think that in the last few years I've learned a lot about myself, about the things
that really intrigued me, that push me to excel. I love coding, I love talking with
people,&amp;nbsp;mentoring, lecturing about technologies or Agile methodologies, but most
of all -&amp;nbsp;I enjoy taking ownership&amp;nbsp;of projects I participate in and making
them successful.&amp;nbsp;I'm looking to surround myself with people smarter than me,
those that have natural gifts in them, and making them better.
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;Things I should do&lt;/strong&gt;
&lt;/p&gt;
&lt;p&gt;
I should try to get more organized in planning my time. I read a lot of books about
self management but I don't feel like I'm practicing them as much as I should. I should
really invest more time in myself, trying to set goals and constantly reviewing them.
I'm leading the Agile a la Scrum at Semingo so I hope to use this work &amp;amp; review&amp;nbsp;notion
more in my life.
&lt;/p&gt;
&lt;p&gt;
I should learn more about Agile, Scrum and XP. I've read&amp;nbsp;a few&amp;nbsp;great books
about Agile\Scrum\Management but I still have a lot of unanswered questions. I know
that these methodologies only offer some solutions but I don't believe we should enforce
them. I believe in making&amp;nbsp;our own Agile process at Semingo. That said, I do want
to read more books from people with different experience, different ideas and best
practices I could learn from.
&lt;/p&gt;
&lt;p&gt;
I should definitely write more posts! (particularly about Agile\Scrum)
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;Things I want to do&lt;/strong&gt;
&lt;/p&gt;
&lt;p&gt;
TDD: getting better in it and start lecturing about it more.&lt;br&gt;
Multi-threading: This one is a new set of skills I'm developing at my current job.
Looking at the near future, this skill is crucial as a developer.&lt;br&gt;
WCF: I need to use it in my current job and I have a lot of catch up to do.&lt;br&gt;
Lecturing: At least 4-5 lectures a year looks like a solid goal at the moment.&lt;br&gt;
&lt;br&gt;
Most of all, I want to make Semingo the best place to work at, to bring more amazing
guys&amp;amp;gals to work with us and making an application that will change the way millions
of people work.&lt;br&gt;
&lt;strong&gt;
&lt;br&gt;
Things I won't do&lt;/strong&gt;
&lt;/p&gt;
&lt;p&gt;
I think that it's getting clear to me that I do not want to be an external coach.
I don't see myself coaching a team for a 2-3 months and then shifting to another team.
I enjoy working with people and I take pride and strength in making things complete.
&lt;/p&gt;
&lt;p&gt;
I won't stop talking and writing about software, practices and people as long as I
have keyboard and working set of 1-N fingers available. Count on it!
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;
&lt;br&gt;
Tagging these folks&lt;/strong&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://www.pashabitz.com/"&gt;Pasha Bitz&lt;/a&gt;,&amp;nbsp;&lt;a href="http://www.human-debugger.net/"&gt;Shani
Raba&lt;/a&gt;, &lt;a href="http://doronsharp.spaces.live.com/"&gt;Doron Yaacoby&lt;/a&gt;, &lt;a href="http://www.eranachum.com/"&gt;Eran
Nachum&lt;/a&gt;, &lt;a href="http://www.kenegozi.com/blog/"&gt;Ken Egozi&lt;/a&gt;
&lt;/p&gt;
&lt;img width="0" height="0" src="http://lnbogen.com/aggbug.ashx?id=055de749-53f4-4fe4-b223-9b77ca49a280" /&gt;</description>
      <comments>http://lnbogen.com/CommentView,guid,055de749-53f4-4fe4-b223-9b77ca49a280.aspx</comments>
      <category>Life</category>
    </item>
    <item>
      <trackback:ping>http://lnbogen.com/Trackback.aspx?guid=5fd4e00e-f09b-4348-b2c3-c8b2c7248f27</trackback:ping>
      <pingback:server>http://lnbogen.com/pingback.aspx</pingback:server>
      <pingback:target>http://lnbogen.com/PermaLink,guid,5fd4e00e-f09b-4348-b2c3-c8b2c7248f27.aspx</pingback:target>
      <dc:creator>Oren Ellenbogen</dc:creator>
      <wfw:comment>http://lnbogen.com/CommentView,guid,5fd4e00e-f09b-4348-b2c3-c8b2c7248f27.aspx</wfw:comment>
      <wfw:commentRss>http://lnbogen.com/SyndicationService.asmx/GetEntryCommentsRss?guid=5fd4e00e-f09b-4348-b2c3-c8b2c7248f27</wfw:commentRss>
      <slash:comments>1</slash:comments>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
One of the downsides of using <font color="#0000ff">lock</font> is obviously
performance. While locking an object, any other thread trying to acquire the
lock on that object will wait in line. This can open up a deep hole to performance
hit. Rule of thumb while working with locks is to acquire it as late as possible and
release it as soon as possible. To demonstrate the order of magnitude bad usage
of locks can affect your performance, I decided to write a little demo. <br />
So let's assume we have a component that is responsible for executing tasks while
getting new ones in the process (on different threads). I tried to make this example
as simple as possible. Let's start with our "task" class:
</p>
        <p>
          <span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">
            <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">public</span>
            <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">class</span> Task<br />
{<br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">   private</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">int</span> _id;<br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">   private</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">string</span> _name;<br /><br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">   public</span> Task(<span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">int</span> id, <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">string</span> name) {<br />
      _id <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span> id;<br />
      _name <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span> name;<br />
   }<br /><br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">   public</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">int</span> Id { <span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">//
getter, setter </span>}<br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">   public</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">string</span> Name { <span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">//
getter, setter </span>}<br />
}</span>
        </p>
        <p>
We have a TasksRunner that's responsible for getting new tasks and saving it to internal
list and executing the current tasks every X milliseconds (via timer). In order
to simulate a real-life process, I've made sure that executing a single task is expensive. Let's
start with the non-optimized solution:
</p>
        <p>
          <span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">
            <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">public</span>
            <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">class</span> TasksRunner<br />
{<br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">   private</span> List&lt;Task&gt;
_tasks;<br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">   private</span> System.Timers.Timer
_handleTasksTimer;<br /><br />
   <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">public</span> TasksRunner()<br />
   {<br />
      _tasks <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">new</span> List&lt;Task&gt;();<br /><br />
      _handleTasksTimer <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">new</span> Timer(200); <br />
      _handleTasksTimer.Elapsed += <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">new</span> System.Timers.ElapsedEventHandler(_handleTasksTimer_Elapsed);<br />
      _handleTasksTimer.Start();<br />
   }<br /></span>
        </p>
        <p>
          <span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">
            <font color="#0000ff">   public</font>
            <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">void</span> AddTask(Task
t)<br />
   {<br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">      lock</span> (_tasks)<br />
      {<br />
         _tasks.Add(t);<br />
         Console.WriteLine(<span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4">"Task
added, id: "</span><span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">+</span> t.Id <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">+</span><span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4">",
name: "</span><span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">+</span> t.Name);<br />
      }<br />
   }<br /><br /><span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">   //Execute
the (delta) tasks in a thread from the ThreadPool</span><br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">   private</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">void</span> _handleTasksTimer_Elapsed(<span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">object</span> sender,
System.Timers.ElapsedEventArgs e)<br />
   {<br />
      ExecuteCurrentTasks();<br />
   }<br /><br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">   public</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">void</span> ExecuteCurrentTasks()<br />
   {<br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">      lock</span> (_tasks)<br />
      {<br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">         foreach</span> (Task
t <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">in</span> _tasks)<br />
            ExecuteSingleTask(t);<br />
         <br />
         _tasks.Clear();<br />
      }<br />
   }<br /><br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">   private</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">void</span> ExecuteSingleTask(Task
t)<br />
   {<br />
      Console.WriteLine(<span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4">"Handling
task, id: "</span><span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">+</span> t.Id <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">+</span><span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4">",
name: "</span><span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">+</span> t.Name);<br />
      Thread.Sleep(1000); <span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">//simulate
long run</span><br />
   }<br />
}</span>
        </p>
        <p>
AddTask will acquire the lock on _tasks and add the new task to the list while ExecuteCurrentTasks
will acquire the lock (on _tasks) and simulate real execution on the task. Notice
that during the execution, calling AddTask will wait until the current execution will
be finished. Using <a href="http://weblogs.asp.net/rosherove/default.aspx">Roy</a>'s <a href="http://weblogs.asp.net/rosherove/archive/2007/06/25/threadtester-with-new-ability-stopwhentrue-and-thread-polling.aspx">ThreadTester</a>,
we can run the following in order to notice the behavior so far:
</p>
        <p>
          <span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">
            <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">static</span>
            <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">void</span> Main(<span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">string</span>[]
args)<br />
{<br />
   TasksRunner runner <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">new</span> TasksRunner();<br />
   ThreadTester threadTester <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">new</span> ThreadTester();<br />
   threadTester.RunBehavior <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span> ThreadRunBehavior.RunUntilAllThreadsFinish;<br /><br />
   Stopwatch watch <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">new</span> Stopwatch();<br />
   watch.Start();<br /><br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">   int</span> numberOfTasksToCreate <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span> 100;<br />
   threadTester.AddThreadAction(<span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">delegate</span><br />
      {<br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">         for</span> (<span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">int</span> j <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span> 0;
j &lt; numberOfTasksToCreate; j++) <br />
         {<br />
            runner.AddTask(<span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">new</span> Task(j, <span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4">"job
"</span><span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">+</span> j));<br />
            Thread.Sleep(100);<br />
         }<br />
      });<br /><br />
   threadTester.StartAllThreads(<span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">int</span>.MaxValue); <span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">//wait,
no matter how long</span><br /><br />
   Console.WriteLine(<span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4">"Total
time so far (milliseconds): "</span><span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">+</span> watch.ElapsedMilliseconds);<br />
   Console.WriteLine(<span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4">"Tasks
added so far: "</span><span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">+</span> runner.TasksAdded);<br />
   Console.WriteLine(<span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4">"Tasks
executed so far: "</span><span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">+</span> runner.TasksExecuted);<br />
   Console.WriteLine(<span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4">"Waiting
for tasks to end..."</span>);<br /><br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">   while</span> (runner.TasksExecuted
&lt; numberOfTasksToCreate)<br />
      Thread.Sleep(1000);<br /><br />
   runner.Shutdown();<br /><br />
   Console.WriteLine(<span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4">"done!"</span>);<br />
   Console.WriteLine(<span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4">"Total
time so far (milliseconds): "</span><span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">+</span> watch.ElapsedMilliseconds);<br />
   Console.WriteLine(<span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4">"Tasks
added so far: "</span><span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">+</span> runner.TasksAdded);<br />
   Console.WriteLine(<span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4">"Tasks
executed so far: "</span><span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">+</span> runner.TasksExecuted);<br />
}</span>
        </p>
        <p>
Running this test will give us a very poor result for adding &amp; executing
100 tasks takes around ~99 seconds. 
</p>
        <p>
No doubt, the lock on _tasks while executing each and every task in the list is too
expensive as we're depend on ExecuteSingleTask (which is expensive by itself). This
way, each new task we're trying to add must wait until the current execution
is finished. An elegant solution to this problem, suggested by my teammate <a href="http://www.tomergabel.com/">Tomer
Gabel</a>, is to use a temporal object to point to the current tasks thus freeing
the lock much quicker. So here is an optimized version of ExecuteCurrentTasks:
</p>
        <p>
          <span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">
            <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">public</span>
            <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">void</span> ExecuteCurrentTasks()<br />
{<br />
   List&lt;Task&gt; copyOfTasks <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">null</span>;<br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">   lock</span> (_tasks)<br />
   {<br />
      copyOfTasks <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span> _tasks;<br />
      _tasks <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">new</span> List&lt;Task&gt;();<br />
   }<br /><br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">   foreach</span> (Task
t <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">in</span> copyOfTasks)<br />
      ExecuteSingleTask(t);<br />
}</span>
        </p>
        <p>
This little refactoring give us around ~11 seconds for adding &amp; executing 100
tasks. 
</p>
        <p>
Smoking!
</p>
        <img width="0" height="0" src="http://lnbogen.com/aggbug.ashx?id=5fd4e00e-f09b-4348-b2c3-c8b2c7248f27" />
      </body>
      <title>Bring lock back until 12, it has a busy day tomorrow</title>
      <guid isPermaLink="false">http://lnbogen.com/PermaLink,guid,5fd4e00e-f09b-4348-b2c3-c8b2c7248f27.aspx</guid>
      <link>http://lnbogen.com/2007/07/12/BringLockBackUntil12ItHasABusyDayTomorrow.aspx</link>
      <pubDate>Thu, 12 Jul 2007 09:44:41 GMT</pubDate>
      <description>&lt;p&gt;
One of the&amp;nbsp;downsides of using &lt;font color=#0000ff&gt;lock&lt;/font&gt; is obviously performance.&amp;nbsp;While
locking an object, any other thread trying to acquire the lock on that object will
wait in line. This can open up a deep hole to performance hit. Rule of thumb while
working with locks is to acquire it as late as possible and release it as soon as
possible. To&amp;nbsp;demonstrate the order of magnitude bad usage of locks can affect
your performance, I decided to write a little demo.&amp;nbsp;&lt;br&gt;
So let's assume we have a component that is responsible for executing tasks while
getting new ones in the process (on different threads). I tried to make this example
as simple as possible. Let's start with our "task" class:
&lt;/p&gt;
&lt;p&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;public&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;class&lt;/span&gt; Task&lt;br&gt;
{&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;private&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;int&lt;/span&gt; _id;&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;private&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;string&lt;/span&gt; _name;&lt;br&gt;
&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;public&lt;/span&gt; Task(&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;int&lt;/span&gt; id, &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;string&lt;/span&gt; name)&amp;nbsp;{&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;_id &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; id;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;_name &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; name;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br&gt;
&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;public&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;int&lt;/span&gt; Id&amp;nbsp;{&amp;nbsp;&lt;span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;//
getter, setter&amp;nbsp;&lt;/span&gt;}&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;public&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;string&lt;/span&gt; Name&amp;nbsp;{&amp;nbsp;&lt;span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;//
getter, setter&amp;nbsp;&lt;/span&gt;}&lt;br&gt;
}&lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
We have a TasksRunner that's responsible for getting new tasks and saving it to internal
list and executing the current tasks every&amp;nbsp;X milliseconds (via timer). In order
to simulate a real-life process, I've made sure that executing a single task is expensive.&amp;nbsp;Let's
start with the non-optimized&amp;nbsp;solution:
&lt;/p&gt;
&lt;p&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;public&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;class&lt;/span&gt; TasksRunner&lt;br&gt;
{&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;private&lt;/span&gt; List&amp;lt;Task&amp;gt;
_tasks;&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;private&lt;/span&gt; System.Timers.Timer
_handleTasksTimer;&lt;br&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;public&lt;/span&gt; TasksRunner()&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;_tasks &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;new&lt;/span&gt; List&amp;lt;Task&amp;gt;();&lt;br&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;_handleTasksTimer &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;new&lt;/span&gt; Timer(200);&amp;nbsp;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;_handleTasksTimer.Elapsed += &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;new&lt;/span&gt; System.Timers.ElapsedEventHandler(_handleTasksTimer_Elapsed);&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;_handleTasksTimer.Start();&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br&gt;
&lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&lt;font color=#0000ff&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;public&lt;/font&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;void&lt;/span&gt; AddTask(Task
t)&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;lock&lt;/span&gt; (_tasks)&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;_tasks.Add(t);&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Console.WriteLine(&lt;span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4"&gt;"Task
added, id: "&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;+&lt;/span&gt; t.Id &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;+&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4"&gt;",
name: "&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;+&lt;/span&gt; t.Name);&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br&gt;
&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;//Execute
the (delta) tasks in a thread from the ThreadPool&lt;/span&gt;
&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;private&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;void&lt;/span&gt; _handleTasksTimer_Elapsed(&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;object&lt;/span&gt; sender,
System.Timers.ElapsedEventArgs e)&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;ExecuteCurrentTasks();&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br&gt;
&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;public&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;void&lt;/span&gt; ExecuteCurrentTasks()&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;lock&lt;/span&gt; (_tasks)&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;foreach&lt;/span&gt; (Task
t &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;in&lt;/span&gt; _tasks)&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;ExecuteSingleTask(t);&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;_tasks.Clear();&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br&gt;
&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;private&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;void&lt;/span&gt; ExecuteSingleTask(Task
t)&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Console.WriteLine(&lt;span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4"&gt;"Handling
task, id: "&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;+&lt;/span&gt; t.Id &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;+&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4"&gt;",
name: "&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;+&lt;/span&gt; t.Name);&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Thread.Sleep(1000); &lt;span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;//simulate
long run&lt;/span&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br&gt;
}&lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
AddTask will acquire the lock on _tasks and add the new task to the list while ExecuteCurrentTasks
will acquire the lock (on _tasks) and simulate real execution on the task. Notice
that during the execution, calling AddTask will wait until the current execution will
be finished. Using &lt;a href="http://weblogs.asp.net/rosherove/default.aspx"&gt;Roy&lt;/a&gt;'s &lt;a href="http://weblogs.asp.net/rosherove/archive/2007/06/25/threadtester-with-new-ability-stopwhentrue-and-thread-polling.aspx"&gt;ThreadTester&lt;/a&gt;,
we can run the following in order to notice the behavior so far:
&lt;/p&gt;
&lt;p&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;static&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;void&lt;/span&gt; Main(&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;string&lt;/span&gt;[]
args)&lt;br&gt;
{&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;TasksRunner runner &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;new&lt;/span&gt; TasksRunner();&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;ThreadTester threadTester &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;new&lt;/span&gt; ThreadTester();&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;threadTester.RunBehavior &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; ThreadRunBehavior.RunUntilAllThreadsFinish;&lt;br&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;Stopwatch watch &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;new&lt;/span&gt; Stopwatch();&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;watch.Start();&lt;br&gt;
&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;int&lt;/span&gt; numberOfTasksToCreate &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; 100;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;threadTester.AddThreadAction(&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;delegate&lt;/span&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;for&lt;/span&gt; (&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;int&lt;/span&gt; j &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; 0;
j &amp;lt; numberOfTasksToCreate; j++)&amp;nbsp;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;runner.AddTask(&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;new&lt;/span&gt; Task(j, &lt;span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4"&gt;"job
"&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;+&lt;/span&gt; j));&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Thread.Sleep(100);&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;});&lt;br&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;threadTester.StartAllThreads(&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;int&lt;/span&gt;.MaxValue); &lt;span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;//wait,
no matter how long&lt;/span&gt;
&lt;br&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;Console.WriteLine(&lt;span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4"&gt;"Total
time so far (milliseconds): "&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;+&lt;/span&gt; watch.ElapsedMilliseconds);&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;Console.WriteLine(&lt;span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4"&gt;"Tasks
added so far: "&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;+&lt;/span&gt; runner.TasksAdded);&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;Console.WriteLine(&lt;span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4"&gt;"Tasks
executed so far: "&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;+&lt;/span&gt; runner.TasksExecuted);&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;Console.WriteLine(&lt;span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4"&gt;"Waiting
for tasks to end..."&lt;/span&gt;);&lt;br&gt;
&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;while&lt;/span&gt; (runner.TasksExecuted
&amp;lt; numberOfTasksToCreate)&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Thread.Sleep(1000);&lt;br&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;runner.Shutdown();&lt;br&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;Console.WriteLine(&lt;span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4"&gt;"done!"&lt;/span&gt;);&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;Console.WriteLine(&lt;span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4"&gt;"Total
time so far (milliseconds): "&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;+&lt;/span&gt; watch.ElapsedMilliseconds);&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;Console.WriteLine(&lt;span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4"&gt;"Tasks
added so far: "&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;+&lt;/span&gt; runner.TasksAdded);&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;Console.WriteLine(&lt;span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4"&gt;"Tasks
executed so far: "&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;+&lt;/span&gt; runner.TasksExecuted);&lt;br&gt;
}&lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
Running this test will give us a very poor result&amp;nbsp;for&amp;nbsp;adding &amp;amp; executing
100 tasks takes around ~99 seconds. 
&lt;/p&gt;
&lt;p&gt;
No doubt, the lock on _tasks while executing each and every task in the list is too
expensive as we're depend on ExecuteSingleTask (which is expensive by itself). This
way, each new task&amp;nbsp;we're trying to add must wait until the current execution
is finished.&amp;nbsp;An elegant solution to this problem, suggested by my teammate &lt;a href="http://www.tomergabel.com/"&gt;Tomer
Gabel&lt;/a&gt;, is to use a temporal object to point to the current tasks thus freeing
the lock much quicker. So here is an optimized version of ExecuteCurrentTasks:
&lt;/p&gt;
&lt;p&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;public&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;void&lt;/span&gt; ExecuteCurrentTasks()&lt;br&gt;
{&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;List&amp;lt;Task&amp;gt; copyOfTasks &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;null&lt;/span&gt;;&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;lock&lt;/span&gt; (_tasks)&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;copyOfTasks &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; _tasks;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;_tasks &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;new&lt;/span&gt; List&amp;lt;Task&amp;gt;();&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br&gt;
&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;foreach&lt;/span&gt; (Task
t &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;in&lt;/span&gt; copyOfTasks)&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;ExecuteSingleTask(t);&lt;br&gt;
}&lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
This little refactoring give us around ~11 seconds for adding &amp;amp; executing 100
tasks. 
&lt;/p&gt;
&lt;p&gt;
Smoking!
&lt;/p&gt;
&lt;img width="0" height="0" src="http://lnbogen.com/aggbug.ashx?id=5fd4e00e-f09b-4348-b2c3-c8b2c7248f27" /&gt;</description>
      <comments>http://lnbogen.com/CommentView,guid,5fd4e00e-f09b-4348-b2c3-c8b2c7248f27.aspx</comments>
      <category>.NET</category>
      <category>.Net/Multi-Threading</category>
    </item>
    <item>
      <trackback:ping>http://lnbogen.com/Trackback.aspx?guid=2c40bad0-de27-44db-ad35-a9ff92c3a4c6</trackback:ping>
      <pingback:server>http://lnbogen.com/pingback.aspx</pingback:server>
      <pingback:target>http://lnbogen.com/PermaLink,guid,2c40bad0-de27-44db-ad35-a9ff92c3a4c6.aspx</pingback:target>
      <dc:creator>Oren Ellenbogen</dc:creator>
      <wfw:comment>http://lnbogen.com/CommentView,guid,2c40bad0-de27-44db-ad35-a9ff92c3a4c6.aspx</wfw:comment>
      <wfw:commentRss>http://lnbogen.com/SyndicationService.asmx/GetEntryCommentsRss?guid=2c40bad0-de27-44db-ad35-a9ff92c3a4c6</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
In my previous post, <a href="http://www.lnbogen.com/HowToMockStaticClassOrStaticMemberForTesting.aspx">"How
to mock static class or static member for testing"</a>, Eli replied that mocking
static data can be easily achieved via <a href="www.typemock.com">TypeMock</a> with
no extra work around it. Although Eli raised a valid point while TypeMock is
a very strong framework that you should check out, I still believe that designing
for testability overcomes the basic need for testing your code. Trying to use some
sort of powerful Profiler-based framework in order to mock your "wires"
is a great thing, but I would use it only if refactoring the code will take
too much time or effort that will beat the value of performing the change. 
</p>
        <p>
I would like to make my teammates think toward testability while designing the API.
</p>
        <p>
Breaking your code so it will be easily tested will make things a little bit more
complex in terms of dependency injection (object A will need to get IB in its constructor
in order to work rather then creating new instance of B inside of it), but the allegedly
weakness of breaking your code, making you stray from the pure OOP you've learned
in "OOP for dummies" courses at the university, is the exact strength I
see in TDD. Designing the code by writing use-cases, playing with the API, breaking
classes for Single Responsibility and constant refactoring wins the purpose of
testing solely or pure OO code. Don't get me wrong, pure OO is nice on the surface,
but don't get fooled by it. You write code to create successful software, not
successful practice of old paradigms. 
</p>
        <p>
TDD constantly demands to re-design the system and refactor it to fit the needs the
system invocate, having the tests will back you up in the path. This way you
can follow the guidelines of a sane development process:<br />
1). Design the general architecture (the big picture)<br />
2). Agree on interfaces between components<br />
3). Unit-test user stories (use-cases) and drill down into the design by
each test.<br />
4). Build Integration tests to connect between components.<br /><br />
and so on...
</p>
        <p>
Now, if you want to refactor existing code or add new behaviors, it's simple:<br />
1). Refactor the code.<br />
2). See that everything compiles.<br />
3). Run unit &amp; integrations tests.<br />
4). If all is good - check-in your source.
</p>
        <p>
Claiming that TDD-OO is not pure OO is fine by me. I would prefer TDD-OO based code
on pure OO any day.
</p>
        <img width="0" height="0" src="http://lnbogen.com/aggbug.ashx?id=2c40bad0-de27-44db-ad35-a9ff92c3a4c6" />
      </body>
      <title>Designing for testability overcomes the need for testing</title>
      <guid isPermaLink="false">http://lnbogen.com/PermaLink,guid,2c40bad0-de27-44db-ad35-a9ff92c3a4c6.aspx</guid>
      <link>http://lnbogen.com/2007/07/09/DesigningForTestabilityOvercomesTheNeedForTesting.aspx</link>
      <pubDate>Mon, 09 Jul 2007 13:30:39 GMT</pubDate>
      <description>&lt;p&gt;
In my previous post, &lt;a href="http://www.lnbogen.com/HowToMockStaticClassOrStaticMemberForTesting.aspx"&gt;"How
to mock static class or static member for testing"&lt;/a&gt;, Eli replied that&amp;nbsp;mocking
static data can be&amp;nbsp;easily achieved&amp;nbsp;via&amp;nbsp;&lt;a href="www.typemock.com"&gt;TypeMock&lt;/a&gt;&amp;nbsp;with
no extra work around it. Although Eli raised&amp;nbsp;a valid point while TypeMock is
a very strong framework that you should check out, I still believe that designing
for testability overcomes the basic need for testing your code. Trying to use some
sort of powerful Profiler-based framework&amp;nbsp;in order to mock&amp;nbsp;your "wires"
is a&amp;nbsp;great thing, but I would use it only if&amp;nbsp;refactoring the code will take
too much time or effort&amp;nbsp;that will beat the value of performing the change. 
&lt;/p&gt;
&lt;p&gt;
I would like to make my teammates think toward testability while designing the API.
&lt;/p&gt;
&lt;p&gt;
Breaking your code so it will be easily tested will make things a little bit more
complex in terms of dependency injection (object A will need to get IB in its constructor
in order to work rather then creating new instance of B inside of it), but the allegedly
weakness of breaking your code, making you stray from the pure OOP you've learned
in&amp;nbsp;"OOP for dummies" courses at the university,&amp;nbsp;is the exact strength&amp;nbsp;I
see in TDD. Designing the code by writing use-cases, playing with the API, breaking
classes&amp;nbsp;for Single Responsibility and constant refactoring wins the purpose of
testing solely&amp;nbsp;or pure OO code. Don't get me wrong, pure OO is nice on the surface,
but don't&amp;nbsp;get fooled by it. You write code to create successful software, not
successful practice of old paradigms. 
&lt;/p&gt;
&lt;p&gt;
TDD constantly demands to re-design the system and refactor it to fit the needs the
system invocate, having the&amp;nbsp;tests will back you up in the path. This way you
can follow the guidelines of a sane development process:&lt;br&gt;
1). Design the general architecture (the big picture)&lt;br&gt;
2). Agree on interfaces between components&lt;br&gt;
3). Unit-test&amp;nbsp;user stories (use-cases)&amp;nbsp;and drill down into the design by
each test.&lt;br&gt;
4). Build Integration tests to connect between components.&lt;br&gt;
&lt;br&gt;
and so on...
&lt;/p&gt;
&lt;p&gt;
Now, if you want to refactor existing code or add new behaviors, it's simple:&lt;br&gt;
1). Refactor the code.&lt;br&gt;
2). See that everything compiles.&lt;br&gt;
3). Run unit &amp;amp; integrations tests.&lt;br&gt;
4). If all is good - check-in your source.
&lt;/p&gt;
&lt;p&gt;
Claiming that TDD-OO is not pure OO is fine by me. I would prefer TDD-OO based code
on pure OO any day.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://lnbogen.com/aggbug.ashx?id=2c40bad0-de27-44db-ad35-a9ff92c3a4c6" /&gt;</description>
      <comments>http://lnbogen.com/CommentView,guid,2c40bad0-de27-44db-ad35-a9ff92c3a4c6.aspx</comments>
      <category>TDD</category>
    </item>
    <item>
      <trackback:ping>http://lnbogen.com/Trackback.aspx?guid=9b63928e-832b-40aa-8017-632501cf3177</trackback:ping>
      <pingback:server>http://lnbogen.com/pingback.aspx</pingback:server>
      <pingback:target>http://lnbogen.com/PermaLink,guid,9b63928e-832b-40aa-8017-632501cf3177.aspx</pingback:target>
      <dc:creator>Oren Ellenbogen</dc:creator>
      <wfw:comment>http://lnbogen.com/CommentView,guid,9b63928e-832b-40aa-8017-632501cf3177.aspx</wfw:comment>
      <wfw:commentRss>http://lnbogen.com/SyndicationService.asmx/GetEntryCommentsRss?guid=9b63928e-832b-40aa-8017-632501cf3177</wfw:commentRss>
      <slash:comments>4</slash:comments>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
          <a href="http://www.pashabitz.com/">Pasha Bitz</a>, friend, teammate, hacker and gifted(?)
photographer took some photos on our last Daily Standup Meeting and a few more at
our offices:
</p>
        <p>
          <strong>Daily Standup Meeting (I'm on the left, Sagie(aka Flash)  is
on the right):</strong>
        </p>
        <p>
          <img alt="semingo_standupMeeting_1.jpg" src="http://www.lnbogen.com/content/binary/semingo_standupMeeting_1.jpg" border="0" />
        </p>
        <p>
          <strong>Our office door (notice: it's beta 0.1):</strong>
        </p>
        <p>
          <img alt="semingo_liveInFun.jpg" src="http://www.lnbogen.com/content/binary/semingo_liveInFun.jpg" border="0" />
        </p>
        <p>
          <strong>
            <br />
And finally, the new setup, although it's far from being ready &amp; not updated (I've
got 2 22' inch LCD at the moment):</strong>
        </p>
        <p>
          <img alt="semingo_laptop.jpg" src="http://www.lnbogen.com/content/binary/semingo_laptop.jpg" border="0" />
        </p>
        <p>
          <br />
More pictures we'll be posted soon... 
</p>
        <img width="0" height="0" src="http://lnbogen.com/aggbug.ashx?id=9b63928e-832b-40aa-8017-632501cf3177" />
      </body>
      <title>Photos from the office</title>
      <guid isPermaLink="false">http://lnbogen.com/PermaLink,guid,9b63928e-832b-40aa-8017-632501cf3177.aspx</guid>
      <link>http://lnbogen.com/2007/07/08/PhotosFromTheOffice.aspx</link>
      <pubDate>Sun, 08 Jul 2007 19:39:03 GMT</pubDate>
      <description>&lt;p&gt;
&lt;a href="http://www.pashabitz.com/"&gt;Pasha Bitz&lt;/a&gt;, friend, teammate, hacker and gifted(?)
photographer took some photos on our last Daily Standup Meeting and a few more at
our offices:
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;Daily Standup Meeting (I'm on the left,&amp;nbsp;Sagie(aka&amp;nbsp;Flash) &amp;nbsp;is
on the right):&lt;/strong&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;img alt=semingo_standupMeeting_1.jpg src="http://www.lnbogen.com/content/binary/semingo_standupMeeting_1.jpg" border=0&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;Our office door (notice: it's beta 0.1):&lt;/strong&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;img alt=semingo_liveInFun.jpg src="http://www.lnbogen.com/content/binary/semingo_liveInFun.jpg" border=0&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;
&lt;br&gt;
And finally, the new setup, although it's far from being ready &amp;amp; not updated (I've
got 2 22' inch LCD at the moment):&lt;/strong&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;img alt=semingo_laptop.jpg src="http://www.lnbogen.com/content/binary/semingo_laptop.jpg" border=0&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;br&gt;
More pictures we'll be posted soon... 
&lt;/p&gt;
&lt;img width="0" height="0" src="http://lnbogen.com/aggbug.ashx?id=9b63928e-832b-40aa-8017-632501cf3177" /&gt;</description>
      <comments>http://lnbogen.com/CommentView,guid,9b63928e-832b-40aa-8017-632501cf3177.aspx</comments>
      <category>@ff Topic</category>
    </item>
    <item>
      <trackback:ping>http://lnbogen.com/Trackback.aspx?guid=5d8cc77f-833c-45c9-a4eb-350996fc66a8</trackback:ping>
      <pingback:server>http://lnbogen.com/pingback.aspx</pingback:server>
      <pingback:target>http://lnbogen.com/PermaLink,guid,5d8cc77f-833c-45c9-a4eb-350996fc66a8.aspx</pingback:target>
      <dc:creator>Oren Ellenbogen</dc:creator>
      <wfw:comment>http://lnbogen.com/CommentView,guid,5d8cc77f-833c-45c9-a4eb-350996fc66a8.aspx</wfw:comment>
      <wfw:commentRss>http://lnbogen.com/SyndicationService.asmx/GetEntryCommentsRss?guid=5d8cc77f-833c-45c9-a4eb-350996fc66a8</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
You must admit, I'm a pretty cool (yellow) geek:
</p>
        <p>
          <img height="443" alt="OrenAsSimpson.jpg" src="http://www.lnbogen.com/content/binary/OrenAsSimpson.jpg" width="262" border="0" />
        </p>
        <p>
You can create your own avatar <a href="http://www.simpsonsmovie.com/main.html">here</a>.
</p>
        <img width="0" height="0" src="http://lnbogen.com/aggbug.ashx?id=5d8cc77f-833c-45c9-a4eb-350996fc66a8" />
      </body>
      <title>Lnbogen Simpson avatar</title>
      <guid isPermaLink="false">http://lnbogen.com/PermaLink,guid,5d8cc77f-833c-45c9-a4eb-350996fc66a8.aspx</guid>
      <link>http://lnbogen.com/2007/07/06/LnbogenSimpsonAvatar.aspx</link>
      <pubDate>Fri, 06 Jul 2007 11:41:13 GMT</pubDate>
      <description>&lt;p&gt;
You must admit, I'm a pretty cool (yellow) geek:
&lt;/p&gt;
&lt;p&gt;
&lt;img height=443 alt=OrenAsSimpson.jpg src="http://www.lnbogen.com/content/binary/OrenAsSimpson.jpg" width=262 border=0&gt;
&lt;/p&gt;
&lt;p&gt;
You can create your own avatar &lt;a href="http://www.simpsonsmovie.com/main.html"&gt;here&lt;/a&gt;.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://lnbogen.com/aggbug.ashx?id=5d8cc77f-833c-45c9-a4eb-350996fc66a8" /&gt;</description>
      <comments>http://lnbogen.com/CommentView,guid,5d8cc77f-833c-45c9-a4eb-350996fc66a8.aspx</comments>
      <category>@ff Topic</category>
    </item>
  </channel>
</rss>