<?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:wfw="http://wellformedweb.org/CommentAPI/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:pingback="http://madskills.com/public/xml/rss/module/pingback/" version="2.0">
  <channel>
    <title>Samurai Programmer.com</title>
    <link>http://www.samuraiprogrammer.com/blog/</link>
    <description>I know kung fu</description>
    <language>en-us</language>
    <copyright>Greg Varveris</copyright>
    <lastBuildDate>Sat, 19 Nov 2011 13:45:14 GMT</lastBuildDate>
    <generator>newtelligence dasBlog 2.3.9074.18820</generator>
    <managingEditor>greg@samuraiprogrammer.com</managingEditor>
    <webMaster>greg@samuraiprogrammer.com</webMaster>
    <item>
      <trackback:ping>http://www.samuraiprogrammer.com/blog/Trackback.aspx?guid=640974ce-fd96-4cad-bcd0-6c45ed248018</trackback:ping>
      <pingback:server>http://www.samuraiprogrammer.com/blog/pingback.aspx</pingback:server>
      <pingback:target>http://www.samuraiprogrammer.com/blog/PermaLink,guid,640974ce-fd96-4cad-bcd0-6c45ed248018.aspx</pingback:target>
      <dc:creator>Greg Varveris</dc:creator>
      <wfw:comment>http://www.samuraiprogrammer.com/blog/CommentView,guid,640974ce-fd96-4cad-bcd0-6c45ed248018.aspx</wfw:comment>
      <wfw:commentRss>http://www.samuraiprogrammer.com/blog/SyndicationService.asmx/GetEntryCommentsRss?guid=640974ce-fd96-4cad-bcd0-6c45ed248018</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
So in a code-base I was working in yesterday, we use PInvoke to call out to the Performance
Data Helper (PDH) API’s to collect performance information for machines without using
Perfmon.  One of those PInvoke calls looked like this:
</p>
        <pre class="c#" name="code">/*<br />
PDH_STATUS PdhExpandCounterPath(<br />
LPCTSTR szWildCardPath,<br />
LPTSTR mszExpandedPathList,<br />
LPDWORD pcchPathListLength<br />
);<br />
*/<br />
[DllImport("pdh.dll", CharSet = CharSet.Unicode)]<br />
private static extern PdhStatus PdhExpandCounterPath(<br />
string szWildCardPath,<br />
[MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 3)] char[] mszExpandedPathList,<br />
ref uint pcchPathListLength<br />
);</pre>
        <p>
In .NET 3.5 and below, this PInvoke call works perfectly fine.  In .NET 4.0,
though, I saw this exception:
</p>
        <pre>System.Runtime.InteropServices.MarshalDirectiveException: 
<br />
Cannot marshal 'parameter #2': Array size control parameter index is out of range. 
<br />
at System.Runtime.InteropServices.Marshal.InternalPrelink(IRuntimeMethodInfo m) 
<br />
at System.Runtime.InteropServices.Marshal.Prelink(MethodInfo m)</pre>
        <p>
So, can you identify what’s wrong in the code above?
</p>
        <p>
Well, the Array size control parameter index indicates the zero-based parameter that
contains the count of the array elements, similar to size_is in COM.  Because
the marshaler cannot determine the size of an unmanaged array, you have to pass it
in as a separate parameter.  So in the call above, parameter #2, we specify “SizeParamIndex
= 3” to reference the pcchPathListLength parameter to set the length of the array. 
So what’s the catch?
</p>
        <p>
Well, since the SizeParamIndex is a zero-based index, the 3rd parameter doesn’t really
exist.  So, to fix this, we just change the “SizeParamIndex=3” to “SizeParamIndex=2”
to reference the pcchPathListLength:
</p>
        <pre class="c#" name="code">/*<br />
PDH_STATUS PdhExpandCounterPath(<br />
LPCTSTR szWildCardPath,<br />
LPTSTR mszExpandedPathList,<br />
LPDWORD pcchPathListLength<br />
);<br />
*/<br />
[DllImport("pdh.dll", CharSet = CharSet.Unicode)]<br />
private static extern PdhStatus PdhExpandCounterPath(<br />
string szWildCardPath,<br />
[MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 2)] char[] mszExpandedPathList,<br />
ref uint pcchPathListLength<br />
);</pre>
        <p>
It looks like in .NET 3.5 and below, though, we allowed you to reference either 1-based
index or a zero-based index but in .NET 4.0, we buttoned that up a bit and force you
to use the zero-based index.    Big thanks to my co-worker and frequent
collaborator, <a href="http://blogs.msdn.com/b/pfedev/" target="_blank">Zach Kramer</a> for
his assistance in looking at this issue.
</p>
        <p>
Until Next Time!
</p>
      </body>
      <title>PInvoke Error in .NET 4: Array size control parameter index is out of range</title>
      <guid isPermaLink="false">http://www.samuraiprogrammer.com/blog/PermaLink,guid,640974ce-fd96-4cad-bcd0-6c45ed248018.aspx</guid>
      <link>http://www.samuraiprogrammer.com/blog/2011/11/19/PInvokeErrorInNET4ArraySizeControlParameterIndexIsOutOfRange.aspx</link>
      <pubDate>Sat, 19 Nov 2011 13:45:14 GMT</pubDate>
      <description>&lt;p&gt;
So in a code-base I was working in yesterday, we use PInvoke to call out to the Performance
Data Helper (PDH) API’s to collect performance information for machines without using
Perfmon.&amp;#160; One of those PInvoke calls looked like this:
&lt;/p&gt;
&lt;pre class="c#" name="code"&gt;/*&lt;br /&gt;
PDH_STATUS PdhExpandCounterPath(&lt;br /&gt;
LPCTSTR szWildCardPath,&lt;br /&gt;
LPTSTR mszExpandedPathList,&lt;br /&gt;
LPDWORD pcchPathListLength&lt;br /&gt;
);&lt;br /&gt;
*/&lt;br /&gt;
[DllImport(&amp;quot;pdh.dll&amp;quot;, CharSet = CharSet.Unicode)]&lt;br /&gt;
private static extern PdhStatus PdhExpandCounterPath(&lt;br /&gt;
string szWildCardPath,&lt;br /&gt;
[MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 3)] char[] mszExpandedPathList,&lt;br /&gt;
ref uint pcchPathListLength&lt;br /&gt;
);&lt;/pre&gt;
&lt;p&gt;
In .NET 3.5 and below, this PInvoke call works perfectly fine.&amp;#160; In .NET 4.0,
though, I saw this exception:
&lt;/p&gt;
&lt;pre&gt;System.Runtime.InteropServices.MarshalDirectiveException: 
&lt;br /&gt;
Cannot marshal 'parameter #2': Array size control parameter index is out of range. 
&lt;br /&gt;
at System.Runtime.InteropServices.Marshal.InternalPrelink(IRuntimeMethodInfo m) 
&lt;br /&gt;
at System.Runtime.InteropServices.Marshal.Prelink(MethodInfo m)&lt;/pre&gt;
&lt;p&gt;
So, can you identify what’s wrong in the code above?
&lt;/p&gt;
&lt;p&gt;
Well, the Array size control parameter index indicates the zero-based parameter that
contains the count of the array elements, similar to size_is in COM.&amp;#160; Because
the marshaler cannot determine the size of an unmanaged array, you have to pass it
in as a separate parameter.&amp;#160; So in the call above, parameter #2, we specify “SizeParamIndex
= 3” to reference the pcchPathListLength parameter to set the length of the array.&amp;#160;
So what’s the catch?
&lt;/p&gt;
&lt;p&gt;
Well, since the SizeParamIndex is a zero-based index, the 3rd parameter doesn’t really
exist.&amp;#160; So, to fix this, we just change the “SizeParamIndex=3” to “SizeParamIndex=2”
to reference the pcchPathListLength:
&lt;/p&gt;
&lt;pre class="c#" name="code"&gt;/*&lt;br /&gt;
PDH_STATUS PdhExpandCounterPath(&lt;br /&gt;
LPCTSTR szWildCardPath,&lt;br /&gt;
LPTSTR mszExpandedPathList,&lt;br /&gt;
LPDWORD pcchPathListLength&lt;br /&gt;
);&lt;br /&gt;
*/&lt;br /&gt;
[DllImport(&amp;quot;pdh.dll&amp;quot;, CharSet = CharSet.Unicode)]&lt;br /&gt;
private static extern PdhStatus PdhExpandCounterPath(&lt;br /&gt;
string szWildCardPath,&lt;br /&gt;
[MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 2)] char[] mszExpandedPathList,&lt;br /&gt;
ref uint pcchPathListLength&lt;br /&gt;
);&lt;/pre&gt;
&lt;p&gt;
It looks like in .NET 3.5 and below, though, we allowed you to reference either 1-based
index or a zero-based index but in .NET 4.0, we buttoned that up a bit and force you
to use the zero-based index.&amp;#160;&amp;#160;&amp;#160; Big thanks to my co-worker and frequent
collaborator, &lt;a href="http://blogs.msdn.com/b/pfedev/" target="_blank"&gt;Zach Kramer&lt;/a&gt; for
his assistance in looking at this issue.
&lt;/p&gt;
&lt;p&gt;
Until Next Time!
&lt;/p&gt;</description>
      <comments>http://www.samuraiprogrammer.com/blog/CommentView,guid,640974ce-fd96-4cad-bcd0-6c45ed248018.aspx</comments>
      <category>.NET 4</category>
      <category>Perfmon</category>
      <category>Performance</category>
    </item>
    <item>
      <trackback:ping>http://www.samuraiprogrammer.com/blog/Trackback.aspx?guid=e4740c06-15bc-4ad7-a99a-735725fb5f1c</trackback:ping>
      <pingback:server>http://www.samuraiprogrammer.com/blog/pingback.aspx</pingback:server>
      <pingback:target>http://www.samuraiprogrammer.com/blog/PermaLink,guid,e4740c06-15bc-4ad7-a99a-735725fb5f1c.aspx</pingback:target>
      <dc:creator>Greg Varveris</dc:creator>
      <wfw:comment>http://www.samuraiprogrammer.com/blog/CommentView,guid,e4740c06-15bc-4ad7-a99a-735725fb5f1c.aspx</wfw:comment>
      <wfw:commentRss>http://www.samuraiprogrammer.com/blog/SyndicationService.asmx/GetEntryCommentsRss?guid=e4740c06-15bc-4ad7-a99a-735725fb5f1c</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
So, many apologies for dropping off the face of the blogosphere lately.  Fortunately
(or unfortunately, depending on your perspective), I’ve been really busy at work. 
I’ve been working on some really cool things that I hope I’ll be able to talk about
publicly soon.  For now, though, I wanted to pass on something that I haven’t
seen documented in other places that actually helped me quite a bit lately.  
</p>
        <p>
So, for those of you that generate Word documents via the OpenXML (or any other of
a variety of methods), you may have come across something like this when you opened
up a document you just generated:
</p>
        <p>
          <a href="http://www.samuraiprogrammer.com/blog/content/binary/Windows-Live-Writer/9b44f80892c4_9194/image_2.png">
            <img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://www.samuraiprogrammer.com/blog/content/binary/Windows-Live-Writer/9b44f80892c4_9194/image_thumb.png" width="397" height="167" />
          </a>
        </p>
        <p>
There are some problems with this message but the big one is that it just says “Line:
1, Column: 0”.  Not exactly a map to the error.  As a result, you may have
stared at this message for a long time and wondered – “how the heck do I fix this? 
What is the real problem?”.  Well, let me show you a really quick and easy way
of getting more information than what is initially provided.
</p>
        <h2>Step 1:  Change the extension from docx to zip
</h2>
        <p>
As you may or may not know, all OpenXML documents (or Office documents since Office
2007) are actually zip files at their core. That means you can just crack them open
and peer inside. 
</p>
        <p>
          <a href="http://www.samuraiprogrammer.com/blog/content/binary/Windows-Live-Writer/9b44f80892c4_9194/image_4.png">
            <img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://www.samuraiprogrammer.com/blog/content/binary/Windows-Live-Writer/9b44f80892c4_9194/image_thumb_1.png" width="588" height="77" />
          </a>
        </p>
        <p>
See the difference?  Easy!
</p>
        <h2>Step 2:  Extract the zip file to a folder
</h2>
        <p>
Once again, pretty straight forward.  Once you extract the zip file above, you
should see a structure like the following:
</p>
        <p>
          <a href="http://www.samuraiprogrammer.com/blog/content/binary/Windows-Live-Writer/9b44f80892c4_9194/image_6.png">
            <img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://www.samuraiprogrammer.com/blog/content/binary/Windows-Live-Writer/9b44f80892c4_9194/image_thumb_2.png" width="503" height="162" />
          </a>
        </p>
        <p>
Now, from here – you’ll be able to locate the file referenced in that cryptic error
message above.  
</p>
        <h2>Step 3:  Find the file that’s causing the problem
</h2>
        <p>
In the example above, the message states that the problem lies with the file “/word/document.xml”
so just navigate to the “word” folder and find the “document.xml”.
</p>
        <p>
          <a href="http://www.samuraiprogrammer.com/blog/content/binary/Windows-Live-Writer/9b44f80892c4_9194/image_8.png">
            <img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://www.samuraiprogrammer.com/blog/content/binary/Windows-Live-Writer/9b44f80892c4_9194/image_thumb_3.png" width="594" height="305" />
          </a>
        </p>
        <h2>Step 4:  Open and format the file in Visual Studio
</h2>
        <p>
One of the great features of Visual Studio is that it can format an XML file for you. 
So, in our case, the document.xml file is natively just one big line:
</p>
        <p>
          <a href="http://www.samuraiprogrammer.com/blog/content/binary/Windows-Live-Writer/9b44f80892c4_9194/image_10.png">
            <img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://www.samuraiprogrammer.com/blog/content/binary/Windows-Live-Writer/9b44f80892c4_9194/image_thumb_4.png" width="644" height="57" />
          </a>
        </p>
        <p>
Incidentally, this is why the message always states “Line 1,…” in the error message. 
As far as Word is concerned, the problem IS on the first line.  Fortunately for
us, though, Word can take that single line file and format it for us.  Just use
the Edit &gt; Advanced &gt; Format Document option in Visual Studio:
</p>
        <p>
          <a href="http://www.samuraiprogrammer.com/blog/content/binary/Windows-Live-Writer/9b44f80892c4_9194/image_12.png">
            <img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://www.samuraiprogrammer.com/blog/content/binary/Windows-Live-Writer/9b44f80892c4_9194/image_thumb_5.png" width="615" height="372" />
          </a>
        </p>
        <p>
That will then format the XML and make it look closer to:
</p>
        <p>
          <a href="http://www.samuraiprogrammer.com/blog/content/binary/Windows-Live-Writer/9b44f80892c4_9194/image_14.png">
            <img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://www.samuraiprogrammer.com/blog/content/binary/Windows-Live-Writer/9b44f80892c4_9194/image_thumb_6.png" width="673" height="296" />
          </a>
        </p>
        <h2>Step 5:  Recreate the Word doc and get the additional information
</h2>
        <p>
Now that you have the file formatted appropriately, you can just re-create the Word
document and re-open it.  For this, just go back to the root of the document,
select all the files/folders and then zip it back up:
</p>
        <p>
          <a href="http://www.samuraiprogrammer.com/blog/content/binary/Windows-Live-Writer/9b44f80892c4_9194/image_16.png">
            <img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://www.samuraiprogrammer.com/blog/content/binary/Windows-Live-Writer/9b44f80892c4_9194/image_thumb_7.png" width="668" height="399" />
          </a>
        </p>
        <p>
Once it’s zipped back up again, just change the extension from zip to docx and re-open
the file.  When you do so, you’ll see the following:
</p>
        <p>
          <a href="http://www.samuraiprogrammer.com/blog/content/binary/Windows-Live-Writer/9b44f80892c4_9194/image_18.png">
            <img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://www.samuraiprogrammer.com/blog/content/binary/Windows-Live-Writer/9b44f80892c4_9194/image_thumb_8.png" width="397" height="167" />
          </a>
        </p>
        <p>
          <strong>Note that now, you’ll see that it says “Line: 5667, Column: 0”</strong> –
which will point to the exact line causing the problem – which allows you to just
go back to the “document.xml” file you already have open in Visual Studio to see the
problem.  In our case:
</p>
        <p>
          <a href="http://www.samuraiprogrammer.com/blog/content/binary/Windows-Live-Writer/9b44f80892c4_9194/image_20.png">
            <img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://www.samuraiprogrammer.com/blog/content/binary/Windows-Live-Writer/9b44f80892c4_9194/image_thumb_9.png" width="494" height="171" />
          </a>
        </p>
        <p>
Note that this won’t magically fix your problem.  You’ll still need to examine
the WordML to figure out the problem – but at least you know where to go.  And
knowing is half the battle!  
</p>
        <p>
That’s all for now and I will be back with some more developer stuff soon.  
</p>
        <p>
Until next time!
</p>
      </body>
      <title>Getting more information from the Word error box when troubleshooting OpenXML / WordML issues</title>
      <guid isPermaLink="false">http://www.samuraiprogrammer.com/blog/PermaLink,guid,e4740c06-15bc-4ad7-a99a-735725fb5f1c.aspx</guid>
      <link>http://www.samuraiprogrammer.com/blog/2011/09/03/GettingMoreInformationFromTheWordErrorBoxWhenTroubleshootingOpenXMLWordMLIssues.aspx</link>
      <pubDate>Sat, 03 Sep 2011 16:56:55 GMT</pubDate>
      <description>&lt;p&gt;
So, many apologies for dropping off the face of the blogosphere lately.&amp;#160; Fortunately
(or unfortunately, depending on your perspective), I’ve been really busy at work.&amp;#160;
I’ve been working on some really cool things that I hope I’ll be able to talk about
publicly soon.&amp;#160; For now, though, I wanted to pass on something that I haven’t
seen documented in other places that actually helped me quite a bit lately.&amp;#160; 
&lt;/p&gt;
&lt;p&gt;
So, for those of you that generate Word documents via the OpenXML (or any other of
a variety of methods), you may have come across something like this when you opened
up a document you just generated:
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://www.samuraiprogrammer.com/blog/content/binary/Windows-Live-Writer/9b44f80892c4_9194/image_2.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://www.samuraiprogrammer.com/blog/content/binary/Windows-Live-Writer/9b44f80892c4_9194/image_thumb.png" width="397" height="167" /&gt;&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;
There are some problems with this message but the big one is that it just says “Line:
1, Column: 0”.&amp;#160; Not exactly a map to the error.&amp;#160; As a result, you may have
stared at this message for a long time and wondered – “how the heck do I fix this?&amp;#160;
What is the real problem?”.&amp;#160; Well, let me show you a really quick and easy way
of getting more information than what is initially provided.
&lt;/p&gt;
&lt;h2&gt;Step 1:&amp;#160; Change the extension from docx to zip
&lt;/h2&gt;
&lt;p&gt;
As you may or may not know, all OpenXML documents (or Office documents since Office
2007) are actually zip files at their core. That means you can just crack them open
and peer inside. 
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://www.samuraiprogrammer.com/blog/content/binary/Windows-Live-Writer/9b44f80892c4_9194/image_4.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://www.samuraiprogrammer.com/blog/content/binary/Windows-Live-Writer/9b44f80892c4_9194/image_thumb_1.png" width="588" height="77" /&gt;&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;
See the difference?&amp;#160; Easy!
&lt;/p&gt;
&lt;h2&gt;Step 2:&amp;#160; Extract the zip file to a folder
&lt;/h2&gt;
&lt;p&gt;
Once again, pretty straight forward.&amp;#160; Once you extract the zip file above, you
should see a structure like the following:
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://www.samuraiprogrammer.com/blog/content/binary/Windows-Live-Writer/9b44f80892c4_9194/image_6.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://www.samuraiprogrammer.com/blog/content/binary/Windows-Live-Writer/9b44f80892c4_9194/image_thumb_2.png" width="503" height="162" /&gt;&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;
Now, from here – you’ll be able to locate the file referenced in that cryptic error
message above.&amp;#160; 
&lt;/p&gt;
&lt;h2&gt;Step 3:&amp;#160; Find the file that’s causing the problem
&lt;/h2&gt;
&lt;p&gt;
In the example above, the message states that the problem lies with the file “/word/document.xml”
so just navigate to the “word” folder and find the “document.xml”.
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://www.samuraiprogrammer.com/blog/content/binary/Windows-Live-Writer/9b44f80892c4_9194/image_8.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://www.samuraiprogrammer.com/blog/content/binary/Windows-Live-Writer/9b44f80892c4_9194/image_thumb_3.png" width="594" height="305" /&gt;&lt;/a&gt;
&lt;/p&gt;
&lt;h2&gt;Step 4:&amp;#160; Open and format the file in Visual Studio
&lt;/h2&gt;
&lt;p&gt;
One of the great features of Visual Studio is that it can format an XML file for you.&amp;#160;
So, in our case, the document.xml file is natively just one big line:
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://www.samuraiprogrammer.com/blog/content/binary/Windows-Live-Writer/9b44f80892c4_9194/image_10.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://www.samuraiprogrammer.com/blog/content/binary/Windows-Live-Writer/9b44f80892c4_9194/image_thumb_4.png" width="644" height="57" /&gt;&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;
Incidentally, this is why the message always states “Line 1,…” in the error message.&amp;#160;
As far as Word is concerned, the problem IS on the first line.&amp;#160; Fortunately for
us, though, Word can take that single line file and format it for us.&amp;#160; Just use
the Edit &amp;gt; Advanced &amp;gt; Format Document option in Visual Studio:
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://www.samuraiprogrammer.com/blog/content/binary/Windows-Live-Writer/9b44f80892c4_9194/image_12.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://www.samuraiprogrammer.com/blog/content/binary/Windows-Live-Writer/9b44f80892c4_9194/image_thumb_5.png" width="615" height="372" /&gt;&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;
That will then format the XML and make it look closer to:
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://www.samuraiprogrammer.com/blog/content/binary/Windows-Live-Writer/9b44f80892c4_9194/image_14.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://www.samuraiprogrammer.com/blog/content/binary/Windows-Live-Writer/9b44f80892c4_9194/image_thumb_6.png" width="673" height="296" /&gt;&lt;/a&gt;
&lt;/p&gt;
&lt;h2&gt;Step 5:&amp;#160; Recreate the Word doc and get the additional information
&lt;/h2&gt;
&lt;p&gt;
Now that you have the file formatted appropriately, you can just re-create the Word
document and re-open it.&amp;#160; For this, just go back to the root of the document,
select all the files/folders and then zip it back up:
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://www.samuraiprogrammer.com/blog/content/binary/Windows-Live-Writer/9b44f80892c4_9194/image_16.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://www.samuraiprogrammer.com/blog/content/binary/Windows-Live-Writer/9b44f80892c4_9194/image_thumb_7.png" width="668" height="399" /&gt;&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;
Once it’s zipped back up again, just change the extension from zip to docx and re-open
the file.&amp;#160; When you do so, you’ll see the following:
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://www.samuraiprogrammer.com/blog/content/binary/Windows-Live-Writer/9b44f80892c4_9194/image_18.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://www.samuraiprogrammer.com/blog/content/binary/Windows-Live-Writer/9b44f80892c4_9194/image_thumb_8.png" width="397" height="167" /&gt;&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;Note that now, you’ll see that it says “Line: 5667, Column: 0”&lt;/strong&gt; –
which will point to the exact line causing the problem – which allows you to just
go back to the “document.xml” file you already have open in Visual Studio to see the
problem.&amp;#160; In our case:
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://www.samuraiprogrammer.com/blog/content/binary/Windows-Live-Writer/9b44f80892c4_9194/image_20.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://www.samuraiprogrammer.com/blog/content/binary/Windows-Live-Writer/9b44f80892c4_9194/image_thumb_9.png" width="494" height="171" /&gt;&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;
Note that this won’t magically fix your problem.&amp;#160; You’ll still need to examine
the WordML to figure out the problem – but at least you know where to go.&amp;#160; And
knowing is half the battle!&amp;#160; 
&lt;/p&gt;
&lt;p&gt;
That’s all for now and I will be back with some more developer stuff soon.&amp;#160; 
&lt;/p&gt;
&lt;p&gt;
Until next time!
&lt;/p&gt;</description>
      <comments>http://www.samuraiprogrammer.com/blog/CommentView,guid,e4740c06-15bc-4ad7-a99a-735725fb5f1c.aspx</comments>
      <category>OpenXML</category>
      <category>Troubleshooting</category>
    </item>
    <item>
      <trackback:ping>http://www.samuraiprogrammer.com/blog/Trackback.aspx?guid=90aee052-b425-4e42-82ee-2b736c506e39</trackback:ping>
      <pingback:server>http://www.samuraiprogrammer.com/blog/pingback.aspx</pingback:server>
      <pingback:target>http://www.samuraiprogrammer.com/blog/PermaLink,guid,90aee052-b425-4e42-82ee-2b736c506e39.aspx</pingback:target>
      <dc:creator>Greg Varveris</dc:creator>
      <wfw:comment>http://www.samuraiprogrammer.com/blog/CommentView,guid,90aee052-b425-4e42-82ee-2b736c506e39.aspx</wfw:comment>
      <wfw:commentRss>http://www.samuraiprogrammer.com/blog/SyndicationService.asmx/GetEntryCommentsRss?guid=90aee052-b425-4e42-82ee-2b736c506e39</wfw:commentRss>
      <slash:comments>1</slash:comments>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
          <a href="http://www.hanselman.com/blog/BackToParallelBasicsDontBlockYourThreadsMakeAsyncIOWorkForYou.aspx">Read
a great blog entry by Scott Hanselman</a> recently talking about the parallel dilemma
that I’m sure we’ll see folks face in the future with the (old/new) Parallel classes. 
I wanted to add a few things to this discussion as he focused on the mechanics of
the parallel requests but maybe not the potential effects it could have on the macro
view of your application.  This was originally written as an e-mail I sent to
my team but thought others might find it interesting.
</p>
        <p>
There will be an inclination by people to use the new Parallel functionality in .NET
4.0 to easily spawn operations onto numerous background threads.  That will generally
be okay for console/winform/wpf apps – but could also be potentially bad for ASP.NET
apps as the spawned threads could take away from the processing power and threads
available to process new webpage requests.  I’ll explain more on that later.  
</p>
        <p>
For example, by default, when you do something like Parallel.ForEach(…) or some such,
the parallel library starts firing Tasks to the thread pool so that it can best utilize
the processing power available on your machine (oversimplification but you get the
idea).  The downside is that the thread pool contains a finite number of worker
threads threads available to a process.  Granted, you have about 100 threads
per logical processor in .NET 4 – but it’s worth noting.
</p>
        <p>
While Scott’s entry talks about the new way to implement the Async pattern, I’ve already
seen a bunch of folks use the “Parallel” class because it abstracts away some of the
plumbing of the Async operations and that ease of use could become problematic.  
</p>
        <p>
For example, consider this code:
</p>
        <pre class="c#" name="code">string[] myStrings = { "hello", "world", "you", "crazy", "pfes", "out", "there" };<br /><br />
Parallel.ForEach(myStrings, myString =&gt;<br />
{<br /><br />
System.Console.WriteLine(DateTime.Now + ":" + myString + 
<br />
" - From Thread #" + 
<br />
Thread.CurrentThread.ManagedThreadId);<br />
Thread.Sleep(new Random().Next(1000, 5000));<br /><br />
});<br /></pre>
        <p>
This is a very simple implementation of Parallel’izing a foreach that just writes
some string output with an artificial delay.  Output would be something like:
</p>
        <blockquote>
          <p>
11/16/2010 2:40:05 AM:hello - From Thread #10 
<br />
11/16/2010 2:40:05 AM:crazy - From Thread #11 
<br />
11/16/2010 2:40:05 AM:there - From Thread #12 
<br />
11/16/2010 2:40:06 AM:world - From Thread #13 
<br />
11/16/2010 2:40:06 AM:pfes - From Thread #14 
<br />
11/16/2010 2:40:06 AM:you - From Thread #12 
<br />
11/16/2010 2:40:07 AM:out - From Thread #11  
</p>
        </blockquote>
        <p>
Note the multiple thread ids and extrapolate that out to a server that has more than
just my paltry 2 CPUs.  This can be potentially problematic for ASP.NET applications
as you have a finite number of worker threads available in your worker process and
they must be shared across not just one user but hundreds (or even thousands). 
So, we might see that spawning an operation across tons of threads can potentially
reduce the scalability of your site.
</p>
        <p>
Fortunately, there is a ParallelOptions class where you can set the degree of parallel’ism. 
Updated code as follows:
</p>
        <pre class="c#" name="code">string[] myStrings = { "hello", "world", "you", "crazy", "pfes", "out", "there" };<br /><br />
ParallelOptions options = new ParallelOptions();<br />
options.MaxDegreeOfParallelism = 1;<br /><br />
Parallel.ForEach(myStrings,options, myString =&gt;<br />
{<br /><br />
// Nothing changes here<br />
...<br /><br />
});<br /></pre>
        <p>
This would then output something like:
</p>
        <blockquote>
          <p>
11/16/2010 2:40:11 AM:hello - From Thread #10 
<br />
11/16/2010 2:40:12 AM:world - From Thread #10 
<br />
11/16/2010 2:40:16 AM:you - From Thread #10 
<br />
11/16/2010 2:40:20 AM:crazy - From Thread #10 
<br />
11/16/2010 2:40:23 AM:pfes - From Thread #10 
<br />
11/16/2010 2:40:26 AM:out - From Thread #10 
<br />
11/16/2010 2:40:29 AM:there - From Thread #10
</p>
        </blockquote>
        <p>
Since I set the MaxDegreeOfParallelism to “1”, we see that it just uses the same thread
over and over.  Within reason, that setting *should* correspond to the number
of threads it will use to handle the request.  
</p>
        <h2>Applying to a website
</h2>
        <p>
So, let’s apply the code from the above to a simple website and compare the difference
between the full parallel implementation and the non-parallel implementation. 
The test I used ran for 10 minutes with a consistent load of 20 users on a dual-core
machine running IIS 7. <strong><em></em></strong></p>
        <p>
          <strong>
            <em>In all of the images below, the blue line (or baseline) represents the
single-threaded implementation and the purple line (or compared) represents the parallel
implementation</em>
          </strong>.  
</p>
        <p>
We’ll start with the <strong>request execution time</strong>.  As we’d expect,
the time to complete the request decreases significantly with the parallel implementation.
</p>
        <p>
          <a href="http://www.samuraiprogrammer.com/blog/content/binary/Windows-Live-Writer/df4a939434b1_CB17/__GREGVAR-PC_ASP_NETv4_0_30319_RequestExecutionTime_2.gif">
            <img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="__GREGVAR-PC_ASP_NETv4_0_30319_RequestExecutionTime" border="0" alt="__GREGVAR-PC_ASP_NETv4_0_30319_RequestExecutionTime" src="http://www.samuraiprogrammer.com/blog/content/binary/Windows-Live-Writer/df4a939434b1_CB17/__GREGVAR-PC_ASP_NETv4_0_30319_RequestExecutionTime_thumb.gif" width="484" height="364" />
          </a>
        </p>
        <p>
But what is the cost from a thread perspective?  For that, we’ll look at the <strong>number
of physical threads</strong>: 
</p>
        <p>
          <a href="http://www.samuraiprogrammer.com/blog/content/binary/Windows-Live-Writer/df4a939434b1_CB17/__GREGVAR-PC__NETCLRLocksAndThreads_w3wp__NumofcurrentphysicalThreads_2.gif">
            <img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="__GREGVAR-PC__NETCLRLocksAndThreads_w3wp__NumofcurrentphysicalThreads" border="0" alt="__GREGVAR-PC__NETCLRLocksAndThreads_w3wp__NumofcurrentphysicalThreads" src="http://www.samuraiprogrammer.com/blog/content/binary/Windows-Live-Writer/df4a939434b1_CB17/__GREGVAR-PC__NETCLRLocksAndThreads_w3wp__NumofcurrentphysicalThreads_thumb.gif" width="484" height="364" />
          </a>
        </p>
        <p>
As we’d also expect, there is a significant increase in the number of threads used
in the process.  We go from ~20 threads in the process to a peak of almost 200
threads throughout the test.  Seeing as this was run on a dual-core machine,
we’ll have a maximum of 200 worker threads available in the thread pool.  After
those threads become depleted, you often see requests start getting queued, waiting
for a thread to become available.  So, what happened in our simple test? 
We’re look at the <strong>requests queued</strong> value for that:
</p>
        <p>
          <a href="http://www.samuraiprogrammer.com/blog/content/binary/Windows-Live-Writer/df4a939434b1_CB17/__GREGVAR-PC_ASP_NETv4_0_30319_RequestsQueued_2.gif">
            <img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="__GREGVAR-PC_ASP_NETv4_0_30319_RequestsQueued" border="0" alt="__GREGVAR-PC_ASP_NETv4_0_30319_RequestsQueued" src="http://www.samuraiprogrammer.com/blog/content/binary/Windows-Live-Writer/df4a939434b1_CB17/__GREGVAR-PC_ASP_NETv4_0_30319_RequestsQueued_thumb.gif" width="484" height="364" />
          </a>  
</p>
        <p>
We did, in-fact, start to see a small number of requests become queued throughout
our test.  This indicates that some requests started to pile up waiting for an
available thread to become available.  
</p>
        <p>
Please note that I’m <strong>NOT</strong> saying that you should not use Parallel
operations in your website.  <strong>You saw in the first image that the actual
request execution time decreased significantly from the non-parallel implementation
to the parallel implementation.</strong> But it’s important to note that nothing is
free and while parallelizing your work can and will improve the performance of a single
request, it should also be weighed against the potential performance of your site
overall.
</p>
        <p>
Until next time.
</p>
      </body>
      <title>The (potentially) dark side of parallelism…</title>
      <guid isPermaLink="false">http://www.samuraiprogrammer.com/blog/PermaLink,guid,90aee052-b425-4e42-82ee-2b736c506e39.aspx</guid>
      <link>http://www.samuraiprogrammer.com/blog/2010/12/05/ThePotentiallyDarkSideOfParallelism.aspx</link>
      <pubDate>Sun, 05 Dec 2010 18:52:17 GMT</pubDate>
      <description>&lt;p&gt;
&lt;a href="http://www.hanselman.com/blog/BackToParallelBasicsDontBlockYourThreadsMakeAsyncIOWorkForYou.aspx"&gt;Read
a great blog entry by Scott Hanselman&lt;/a&gt; recently talking about the parallel dilemma
that I’m sure we’ll see folks face in the future with the (old/new) Parallel classes.&amp;#160;
I wanted to add a few things to this discussion as he focused on the mechanics of
the parallel requests but maybe not the potential effects it could have on the macro
view of your application.&amp;#160; This was originally written as an e-mail I sent to
my team but thought others might find it interesting.
&lt;/p&gt;
&lt;p&gt;
There will be an inclination by people to use the new Parallel functionality in .NET
4.0 to easily spawn operations onto numerous background threads.&amp;#160; That will generally
be okay for console/winform/wpf apps – but could also be potentially bad for ASP.NET
apps as the spawned threads could take away from the processing power and threads
available to process new webpage requests.&amp;#160; I’ll explain more on that later.&amp;#160; 
&lt;/p&gt;
&lt;p&gt;
For example, by default, when you do something like Parallel.ForEach(…) or some such,
the parallel library starts firing Tasks to the thread pool so that it can best utilize
the processing power available on your machine (oversimplification but you get the
idea).&amp;#160; The downside is that the thread pool contains a finite number of worker
threads threads available to a process.&amp;#160; Granted, you have about 100 threads
per logical processor in .NET 4 – but it’s worth noting.
&lt;/p&gt;
&lt;p&gt;
While Scott’s entry talks about the new way to implement the Async pattern, I’ve already
seen a bunch of folks use the “Parallel” class because it abstracts away some of the
plumbing of the Async operations and that ease of use could become problematic.&amp;#160; 
&lt;/p&gt;
&lt;p&gt;
For example, consider this code:
&lt;/p&gt;
&lt;pre class="c#" name="code"&gt;string[] myStrings = { &amp;quot;hello&amp;quot;, &amp;quot;world&amp;quot;, &amp;quot;you&amp;quot;, &amp;quot;crazy&amp;quot;, &amp;quot;pfes&amp;quot;, &amp;quot;out&amp;quot;, &amp;quot;there&amp;quot; };&lt;br /&gt;
&lt;br /&gt;
Parallel.ForEach(myStrings, myString =&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
&lt;br /&gt;
System.Console.WriteLine(DateTime.Now + &amp;quot;:&amp;quot; + myString + 
&lt;br /&gt;
&amp;quot; - From Thread #&amp;quot; + 
&lt;br /&gt;
Thread.CurrentThread.ManagedThreadId);&lt;br /&gt;
Thread.Sleep(new Random().Next(1000, 5000));&lt;br /&gt;
&lt;br /&gt;
});&lt;br /&gt;
&lt;/pre&gt;
&lt;p&gt;
This is a very simple implementation of Parallel’izing a foreach that just writes
some string output with an artificial delay.&amp;#160; Output would be something like:
&lt;/p&gt;
&lt;blockquote&gt; 
&lt;p&gt;
11/16/2010 2:40:05 AM:hello - From Thread #10 
&lt;br /&gt;
11/16/2010 2:40:05 AM:crazy - From Thread #11 
&lt;br /&gt;
11/16/2010 2:40:05 AM:there - From Thread #12 
&lt;br /&gt;
11/16/2010 2:40:06 AM:world - From Thread #13 
&lt;br /&gt;
11/16/2010 2:40:06 AM:pfes - From Thread #14 
&lt;br /&gt;
11/16/2010 2:40:06 AM:you - From Thread #12 
&lt;br /&gt;
11/16/2010 2:40:07 AM:out - From Thread #11&amp;#160; 
&lt;/p&gt;
&lt;/blockquote&gt; 
&lt;p&gt;
Note the multiple thread ids and extrapolate that out to a server that has more than
just my paltry 2 CPUs.&amp;#160; This can be potentially problematic for ASP.NET applications
as you have a finite number of worker threads available in your worker process and
they must be shared across not just one user but hundreds (or even thousands).&amp;#160;
So, we might see that spawning an operation across tons of threads can potentially
reduce the scalability of your site.
&lt;/p&gt;
&lt;p&gt;
Fortunately, there is a ParallelOptions class where you can set the degree of parallel’ism.&amp;#160;
Updated code as follows:
&lt;/p&gt;
&lt;pre class="c#" name="code"&gt;string[] myStrings = { &amp;quot;hello&amp;quot;, &amp;quot;world&amp;quot;, &amp;quot;you&amp;quot;, &amp;quot;crazy&amp;quot;, &amp;quot;pfes&amp;quot;, &amp;quot;out&amp;quot;, &amp;quot;there&amp;quot; };&lt;br /&gt;
&lt;br /&gt;
ParallelOptions options = new ParallelOptions();&lt;br /&gt;
options.MaxDegreeOfParallelism = 1;&lt;br /&gt;
&lt;br /&gt;
Parallel.ForEach(myStrings,options, myString =&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
&lt;br /&gt;
// Nothing changes here&lt;br /&gt;
...&lt;br /&gt;
&lt;br /&gt;
});&lt;br /&gt;
&lt;/pre&gt;
&lt;p&gt;
This would then output something like:
&lt;/p&gt;
&lt;blockquote&gt; 
&lt;p&gt;
11/16/2010 2:40:11 AM:hello - From Thread #10 
&lt;br /&gt;
11/16/2010 2:40:12 AM:world - From Thread #10 
&lt;br /&gt;
11/16/2010 2:40:16 AM:you - From Thread #10 
&lt;br /&gt;
11/16/2010 2:40:20 AM:crazy - From Thread #10 
&lt;br /&gt;
11/16/2010 2:40:23 AM:pfes - From Thread #10 
&lt;br /&gt;
11/16/2010 2:40:26 AM:out - From Thread #10 
&lt;br /&gt;
11/16/2010 2:40:29 AM:there - From Thread #10
&lt;/p&gt;
&lt;/blockquote&gt; 
&lt;p&gt;
Since I set the MaxDegreeOfParallelism to “1”, we see that it just uses the same thread
over and over.&amp;#160; Within reason, that setting *should* correspond to the number
of threads it will use to handle the request.&amp;#160; 
&lt;/p&gt;
&lt;h2&gt;Applying to a website
&lt;/h2&gt;
&lt;p&gt;
So, let’s apply the code from the above to a simple website and compare the difference
between the full parallel implementation and the non-parallel implementation.&amp;#160;
The test I used ran for 10 minutes with a consistent load of 20 users on a dual-core
machine running IIS 7. &lt;strong&gt;&lt;em&gt;&lt;/em&gt;&lt;/strong&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;&lt;em&gt;In all of the images below, the blue line (or baseline) represents the
single-threaded implementation and the purple line (or compared) represents the parallel
implementation&lt;/em&gt;&lt;/strong&gt;.&amp;#160; 
&lt;/p&gt;
&lt;p&gt;
We’ll start with the &lt;strong&gt;request execution time&lt;/strong&gt;.&amp;#160; As we’d expect,
the time to complete the request decreases significantly with the parallel implementation.
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://www.samuraiprogrammer.com/blog/content/binary/Windows-Live-Writer/df4a939434b1_CB17/__GREGVAR-PC_ASP_NETv4_0_30319_RequestExecutionTime_2.gif"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="__GREGVAR-PC_ASP_NETv4_0_30319_RequestExecutionTime" border="0" alt="__GREGVAR-PC_ASP_NETv4_0_30319_RequestExecutionTime" src="http://www.samuraiprogrammer.com/blog/content/binary/Windows-Live-Writer/df4a939434b1_CB17/__GREGVAR-PC_ASP_NETv4_0_30319_RequestExecutionTime_thumb.gif" width="484" height="364" /&gt;&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;
But what is the cost from a thread perspective?&amp;#160; For that, we’ll look at the &lt;strong&gt;number
of physical threads&lt;/strong&gt;: 
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://www.samuraiprogrammer.com/blog/content/binary/Windows-Live-Writer/df4a939434b1_CB17/__GREGVAR-PC__NETCLRLocksAndThreads_w3wp__NumofcurrentphysicalThreads_2.gif"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="__GREGVAR-PC__NETCLRLocksAndThreads_w3wp__NumofcurrentphysicalThreads" border="0" alt="__GREGVAR-PC__NETCLRLocksAndThreads_w3wp__NumofcurrentphysicalThreads" src="http://www.samuraiprogrammer.com/blog/content/binary/Windows-Live-Writer/df4a939434b1_CB17/__GREGVAR-PC__NETCLRLocksAndThreads_w3wp__NumofcurrentphysicalThreads_thumb.gif" width="484" height="364" /&gt;&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;
As we’d also expect, there is a significant increase in the number of threads used
in the process.&amp;#160; We go from ~20 threads in the process to a peak of almost 200
threads throughout the test.&amp;#160; Seeing as this was run on a dual-core machine,
we’ll have a maximum of 200 worker threads available in the thread pool.&amp;#160; After
those threads become depleted, you often see requests start getting queued, waiting
for a thread to become available.&amp;#160; So, what happened in our simple test?&amp;#160;
We’re look at the &lt;strong&gt;requests queued&lt;/strong&gt; value for that:
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://www.samuraiprogrammer.com/blog/content/binary/Windows-Live-Writer/df4a939434b1_CB17/__GREGVAR-PC_ASP_NETv4_0_30319_RequestsQueued_2.gif"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="__GREGVAR-PC_ASP_NETv4_0_30319_RequestsQueued" border="0" alt="__GREGVAR-PC_ASP_NETv4_0_30319_RequestsQueued" src="http://www.samuraiprogrammer.com/blog/content/binary/Windows-Live-Writer/df4a939434b1_CB17/__GREGVAR-PC_ASP_NETv4_0_30319_RequestsQueued_thumb.gif" width="484" height="364" /&gt;&lt;/a&gt;&amp;#160; 
&lt;/p&gt;
&lt;p&gt;
We did, in-fact, start to see a small number of requests become queued throughout
our test.&amp;#160; This indicates that some requests started to pile up waiting for an
available thread to become available.&amp;#160; 
&lt;/p&gt;
&lt;p&gt;
Please note that I’m &lt;strong&gt;NOT&lt;/strong&gt; saying that you should not use Parallel
operations in your website.&amp;#160; &lt;strong&gt;You saw in the first image that the actual
request execution time decreased significantly from the non-parallel implementation
to the parallel implementation.&lt;/strong&gt; But it’s important to note that nothing is
free and while parallelizing your work can and will improve the performance of a single
request, it should also be weighed against the potential performance of your site
overall.
&lt;/p&gt;
&lt;p&gt;
Until next time.
&lt;/p&gt;</description>
      <comments>http://www.samuraiprogrammer.com/blog/CommentView,guid,90aee052-b425-4e42-82ee-2b736c506e39.aspx</comments>
      <category>.NET 4</category>
      <category>ASP.NET</category>
      <category>Parallel</category>
      <category>Performance</category>
    </item>
    <item>
      <trackback:ping>http://www.samuraiprogrammer.com/blog/Trackback.aspx?guid=79911823-e816-4166-8552-884b2ea29759</trackback:ping>
      <pingback:server>http://www.samuraiprogrammer.com/blog/pingback.aspx</pingback:server>
      <pingback:target>http://www.samuraiprogrammer.com/blog/PermaLink,guid,79911823-e816-4166-8552-884b2ea29759.aspx</pingback:target>
      <dc:creator>Greg Varveris</dc:creator>
      <wfw:comment>http://www.samuraiprogrammer.com/blog/CommentView,guid,79911823-e816-4166-8552-884b2ea29759.aspx</wfw:comment>
      <wfw:commentRss>http://www.samuraiprogrammer.com/blog/SyndicationService.asmx/GetEntryCommentsRss?guid=79911823-e816-4166-8552-884b2ea29759</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <blockquote>
          <p>
            <strong>
              <em>“We shall neither fail nor falter; we shall not weaken or tire…give us
the tools and we will finish the job.” – Winston Churchill</em>
            </strong>
          </p>
        </blockquote>
        <p>
I don’t often blog about specific language features but over the past few weeks I’ve
spoken to a few folks that did not know of the <a href="http://msdn.microsoft.com/en-us/library/9k7k7cf0.aspx">“yield”
keyword and the “yield return” and “yield break” statements</a>, so I thought it might
be a good opportunity to shed some light on this little known but extremely useful
C# feature.  Chances are, you’ve probably indirectly used this feature before
and just never known it.
</p>
        <p>
We’ll start with the problem I’ve seen that plagues many applications.  Often
times, you’ll call a method that returns a List&lt;T&gt; or some other concrete collection. 
The method probably looks something like this:
</p>
        <pre class="c#" name="code">public static List&lt;string&gt; GenerateMyList()<br />
{<br />
List&lt;string&gt; myList = new List&lt;string&gt;();<br /><br />
for (int i = 0; i &lt; 100; i++)<br />
{<br /><br />
myList.Add(i.ToString()); 
<br /><br />
}<br /><br />
return myList;<br /><br />
}</pre>
        <p>
I’m sure your logic is going to be significantly more complex than what I have above
but you get the idea.  There are a few problems and inefficiencies with this
method.  Can you spot them?
</p>
        <ul>
          <li>
The entire List&lt;T&gt; must be stored in memory. 
</li>
          <li>
Its caller must wait for the List&lt;T&gt; to be returned before it can process anything. 
</li>
          <li>
The method itself returns a List&lt;T&gt; back to its caller. 
</li>
        </ul>
        <p>
          <em>As an aside – with public methods, you should strive to not return a List&lt;T&gt;
in your methods.  </em>
          <a href="http://msdn.microsoft.com/en-us/library/ms182142.aspx">
            <em>Full
details can be found here</em>
          </a>
          <em>.  The main idea here is that if you choose
to change the method signature and return a different collection type in the future,
this would be considered a breaking change to your callers.</em>
        </p>
        <p>
In any case, I’ll focus on the first two items in the list above.  If the List&lt;T&gt;
that is returned from the GenerateMyList() method is large then that will be a lot
of data that must be kept around in memory.  In addition, if it takes a long
time to generate the list, your caller is stuck until you’ve completely finished your
processing.
</p>
        <p>
Instead, you can use that nifty “<strong>yield</strong>” keyword.  This allows
the GenerateMyList() method to return items to its caller as they are being processed. 
This means that you no longer need to keep the entire list in memory and can just
return one item at a time until you get to the end of your returned items.  To
illustrate my point, I’ll refactor the above method into the following:
</p>
        <pre class="c#" name="code">private static IEnumerable&lt;string&gt; GenerateMyList()<br />
{<br />
for (int i = 0; i &lt; 100; i++)<br />
{<br />
string value = i.ToString();<br />
Console.WriteLine("Returning {0} to caller.", value);<br />
yield return value;<br />
}<br /><br />
Console.WriteLine("Method done!");<br /><br />
yield break;<br />
}</pre>
        <p>
A few things to note in this method.  The return type has been changed to an
IEnumerable&lt;string&gt;.  This is one of those nifty interfaces that exposes
an enumerator.  This allows its caller to cycle through the results in a foreach
or while loop.  In addition, the “yield return i.ToString()” will return that
item to its caller at that point and not when the entire method has completed its
processing.  This allows for a very exciting caller-callee type relationship. 
For example, if I call this method like so:
</p>
        <pre class="c#" name="code">IEnumerable&lt;string&gt; myList = GenerateMyList();<br /><br />
foreach (string listItem in myList)<br />
{<br />
Console.WriteLine("Item: " + listItem);<br />
}</pre>
        <p>
The output would be:
</p>
        <p>
          <a href="http://www.samuraiprogrammer.com/blog/content/binary/Windows-Live-Writer/abde526a5631_13833/image_4.png">
            <img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://www.samuraiprogrammer.com/blog/content/binary/Windows-Live-Writer/abde526a5631_13833/image_thumb_1.png" width="257" height="339" />
          </a>
        </p>
        <p>
Thus showing that each item gets returned at the time we processed it.  So, how
does this work?  Well, at compile time, we will generate a class to implement
the behavior in the iterator.  Essentially, this means that the GenerateMyList()
method body gets placed into the MoveNext() method.  In-fact, if you open up
the compiled assembly in <a href="http://www.red-gate.com/products/reflector/">Reflector</a>,
you see that plumbing in place (comments are mine and some code was omitted for clarity’s
sake):
</p>
        <pre class="c#" name="code">private bool MoveNext()<br />
{<br /><br />
this.&lt;&gt;1__state = -1;<br />
this.&lt;i&gt;5__1 = 0;<br />
// My for loop has changed to a while loop.<br />
while (this.&lt;i&gt;5__1 &lt; 100)<br />
{<br />
// Sets a local value<br />
this.&lt;value&gt;5__2 = this.&lt;i&gt;5__1.ToString();<br />
// Here is my Console.WriteLine(...)<br />
Console.WriteLine("Returning {0} to caller.", this.&lt;value&gt;5__2);<br />
// Here is where the current member variable<br />
// gets stored.<br />
this.&lt;&gt;2__current = this.&lt;value&gt;5__2;<br />
this.&lt;&gt;1__state = 1;<br />
// We return "true" to the caller so it knows<br />
// there is another record to be processed.<br />
return true;<br />
...<br />
}<br />
// Here is my Console.WriteLine() at the bottom<br />
// when we've finished processing the loop.<br />
Console.WriteLine("Method done!");<br />
break;<br /><br /><br />
}</pre>
        <p>
Pretty straightforward.  Of course, the real power is that it the compiler converts
the “yield return &lt;blah&gt;” into a nice clean enumerator with a MoveNext(). 
In-fact, if you’ve used LINQ, you’ve probably used this feature without even knowing
it.  Consider the following code:
</p>
        <pre class="c#" name="code">private static void OutputLinqToXmlQuery()<br />
{<br />
XDocument doc = XDocument.Parse<br />
(@"&lt;root&gt;&lt;data&gt;hello world&lt;/data&gt;&lt;data&gt;goodbye world&lt;/data&gt;&lt;/root&gt;");<br /><br />
var results = from data in doc.Descendants("data")<br />
select data;<br /><br />
foreach (var result in results)<br />
{<br />
Console.WriteLine(result); 
<br />
}<br />
}</pre>
        <p>
The “results” object, by default will be of type “WhereSelectEnumerableIterator” which
exposes a MoveNext() method.  In-fact, that is also why the results object doesn’t
allow you to do something like this:
</p>
        <pre class="c#" name="code">var results = from data in doc.Descendants("data")<br />
select data;<br /><br />
var bad = results[1];</pre>
        <p>
The IEnumerator does not expose an indexer allowing you to go straight to a particular
element in the collection because the full collection hasn’t been generated yet. 
Instead, you would do something like this:
</p>
        <pre class="c#" name="code">var results = from data in doc.Descendants("data")<br />
select data; 
<br /><br />
var good = results.ElementAt(1);</pre>
        <p>
And then under the covers, the ElementAt(int) method will just keep calling MoveNext()
until it reaches the index you specified.  Something like this: 
</p>
        <blockquote>
          <p>
            <strong>
              <em>Note:  this is my own code and is NOT from the .NET Framework – it
is merely meant to illustrate a point.</em>
            </strong>
          </p>
        </blockquote>
        <pre class="c#" name="code">public static XElement MyElementAt(this IEnumerable&lt;XElement&gt; elements, 
<br />
int index)<br />
{<br />
int counter = 0;<br />
using (IEnumerator&lt;XElement&gt; enumerator = 
<br />
elements.GetEnumerator())<br />
{ 
<br />
while(enumerator.MoveNext()){<br />
if (counter == index)<br />
return enumerator.Current;<br />
counter++;<br />
}<br />
}<br /><br />
return null;<br />
}</pre>
        <p>
Hope this helps to demystify some things and put another tool in your toolbox.
</p>
        <p>
Until next time.
</p>
      </body>
      <title>Yield Return…a little known but incredible language feature</title>
      <guid isPermaLink="false">http://www.samuraiprogrammer.com/blog/PermaLink,guid,79911823-e816-4166-8552-884b2ea29759.aspx</guid>
      <link>http://www.samuraiprogrammer.com/blog/2010/10/17/YieldReturnaLittleKnownButIncredibleLanguageFeature.aspx</link>
      <pubDate>Sun, 17 Oct 2010 22:54:49 GMT</pubDate>
      <description>&lt;blockquote&gt; 
&lt;p&gt;
&lt;strong&gt;&lt;em&gt;“We shall neither fail nor falter; we shall not weaken or tire…give us
the tools and we will finish the job.” – Winston Churchill&lt;/em&gt;&lt;/strong&gt;
&lt;/p&gt;
&lt;/blockquote&gt; 
&lt;p&gt;
I don’t often blog about specific language features but over the past few weeks I’ve
spoken to a few folks that did not know of the &lt;a href="http://msdn.microsoft.com/en-us/library/9k7k7cf0.aspx"&gt;“yield”
keyword and the “yield return” and “yield break” statements&lt;/a&gt;, so I thought it might
be a good opportunity to shed some light on this little known but extremely useful
C# feature.&amp;#160; Chances are, you’ve probably indirectly used this feature before
and just never known it.
&lt;/p&gt;
&lt;p&gt;
We’ll start with the problem I’ve seen that plagues many applications.&amp;#160; Often
times, you’ll call a method that returns a List&amp;lt;T&amp;gt; or some other concrete collection.&amp;#160;
The method probably looks something like this:
&lt;/p&gt;
&lt;pre class="c#" name="code"&gt;public static List&amp;lt;string&amp;gt; GenerateMyList()&lt;br /&gt;
{&lt;br /&gt;
List&amp;lt;string&amp;gt; myList = new List&amp;lt;string&amp;gt;();&lt;br /&gt;
&lt;br /&gt;
for (int i = 0; i &amp;lt; 100; i++)&lt;br /&gt;
{&lt;br /&gt;
&lt;br /&gt;
myList.Add(i.ToString()); 
&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
return myList;&lt;br /&gt;
&lt;br /&gt;
}&lt;/pre&gt;
&lt;p&gt;
I’m sure your logic is going to be significantly more complex than what I have above
but you get the idea.&amp;#160; There are a few problems and inefficiencies with this
method.&amp;#160; Can you spot them?
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
The entire List&amp;lt;T&amp;gt; must be stored in memory. 
&lt;/li&gt;
&lt;li&gt;
Its caller must wait for the List&amp;lt;T&amp;gt; to be returned before it can process anything. 
&lt;/li&gt;
&lt;li&gt;
The method itself returns a List&amp;lt;T&amp;gt; back to its caller. 
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
&lt;em&gt;As an aside – with public methods, you should strive to not return a List&amp;lt;T&amp;gt;
in your methods.&amp;#160; &lt;/em&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/ms182142.aspx"&gt;&lt;em&gt;Full
details can be found here&lt;/em&gt;&lt;/a&gt;&lt;em&gt;.&amp;#160; The main idea here is that if you choose
to change the method signature and return a different collection type in the future,
this would be considered a breaking change to your callers.&lt;/em&gt;
&lt;/p&gt;
&lt;p&gt;
In any case, I’ll focus on the first two items in the list above.&amp;#160; If the List&amp;lt;T&amp;gt;
that is returned from the GenerateMyList() method is large then that will be a lot
of data that must be kept around in memory.&amp;#160; In addition, if it takes a long
time to generate the list, your caller is stuck until you’ve completely finished your
processing.
&lt;/p&gt;
&lt;p&gt;
Instead, you can use that nifty “&lt;strong&gt;yield&lt;/strong&gt;” keyword.&amp;#160; This allows
the GenerateMyList() method to return items to its caller as they are being processed.&amp;#160;
This means that you no longer need to keep the entire list in memory and can just
return one item at a time until you get to the end of your returned items.&amp;#160; To
illustrate my point, I’ll refactor the above method into the following:
&lt;/p&gt;
&lt;pre class="c#" name="code"&gt;private static IEnumerable&amp;lt;string&amp;gt; GenerateMyList()&lt;br /&gt;
{&lt;br /&gt;
for (int i = 0; i &amp;lt; 100; i++)&lt;br /&gt;
{&lt;br /&gt;
string value = i.ToString();&lt;br /&gt;
Console.WriteLine(&amp;quot;Returning {0} to caller.&amp;quot;, value);&lt;br /&gt;
yield return value;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
Console.WriteLine(&amp;quot;Method done!&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
yield break;&lt;br /&gt;
}&lt;/pre&gt;
&lt;p&gt;
A few things to note in this method.&amp;#160; The return type has been changed to an
IEnumerable&amp;lt;string&amp;gt;.&amp;#160; This is one of those nifty interfaces that exposes
an enumerator.&amp;#160; This allows its caller to cycle through the results in a foreach
or while loop.&amp;#160; In addition, the “yield return i.ToString()” will return that
item to its caller at that point and not when the entire method has completed its
processing.&amp;#160; This allows for a very exciting caller-callee type relationship.&amp;#160;
For example, if I call this method like so:
&lt;/p&gt;
&lt;pre class="c#" name="code"&gt;IEnumerable&amp;lt;string&amp;gt; myList = GenerateMyList();&lt;br /&gt;
&lt;br /&gt;
foreach (string listItem in myList)&lt;br /&gt;
{&lt;br /&gt;
Console.WriteLine(&amp;quot;Item: &amp;quot; + listItem);&lt;br /&gt;
}&lt;/pre&gt;
&lt;p&gt;
The output would be:
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://www.samuraiprogrammer.com/blog/content/binary/Windows-Live-Writer/abde526a5631_13833/image_4.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://www.samuraiprogrammer.com/blog/content/binary/Windows-Live-Writer/abde526a5631_13833/image_thumb_1.png" width="257" height="339" /&gt;&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;
Thus showing that each item gets returned at the time we processed it.&amp;#160; So, how
does this work?&amp;#160; Well, at compile time, we will generate a class to implement
the behavior in the iterator.&amp;#160; Essentially, this means that the GenerateMyList()
method body gets placed into the MoveNext() method.&amp;#160; In-fact, if you open up
the compiled assembly in &lt;a href="http://www.red-gate.com/products/reflector/"&gt;Reflector&lt;/a&gt;,
you see that plumbing in place (comments are mine and some code was omitted for clarity’s
sake):
&lt;/p&gt;
&lt;pre class="c#" name="code"&gt;private bool MoveNext()&lt;br /&gt;
{&lt;br /&gt;
&lt;br /&gt;
this.&amp;lt;&amp;gt;1__state = -1;&lt;br /&gt;
this.&amp;lt;i&amp;gt;5__1 = 0;&lt;br /&gt;
// My for loop has changed to a while loop.&lt;br /&gt;
while (this.&amp;lt;i&amp;gt;5__1 &amp;lt; 100)&lt;br /&gt;
{&lt;br /&gt;
// Sets a local value&lt;br /&gt;
this.&amp;lt;value&amp;gt;5__2 = this.&amp;lt;i&amp;gt;5__1.ToString();&lt;br /&gt;
// Here is my Console.WriteLine(...)&lt;br /&gt;
Console.WriteLine(&amp;quot;Returning {0} to caller.&amp;quot;, this.&amp;lt;value&amp;gt;5__2);&lt;br /&gt;
// Here is where the current member variable&lt;br /&gt;
// gets stored.&lt;br /&gt;
this.&amp;lt;&amp;gt;2__current = this.&amp;lt;value&amp;gt;5__2;&lt;br /&gt;
this.&amp;lt;&amp;gt;1__state = 1;&lt;br /&gt;
// We return &amp;quot;true&amp;quot; to the caller so it knows&lt;br /&gt;
// there is another record to be processed.&lt;br /&gt;
return true;&lt;br /&gt;
...&lt;br /&gt;
}&lt;br /&gt;
// Here is my Console.WriteLine() at the bottom&lt;br /&gt;
// when we've finished processing the loop.&lt;br /&gt;
Console.WriteLine(&amp;quot;Method done!&amp;quot;);&lt;br /&gt;
break;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
}&lt;/pre&gt;
&lt;p&gt;
Pretty straightforward.&amp;#160; Of course, the real power is that it the compiler converts
the “yield return &amp;lt;blah&amp;gt;” into a nice clean enumerator with a MoveNext().&amp;#160;
In-fact, if you’ve used LINQ, you’ve probably used this feature without even knowing
it.&amp;#160; Consider the following code:
&lt;/p&gt;
&lt;pre class="c#" name="code"&gt;private static void OutputLinqToXmlQuery()&lt;br /&gt;
{&lt;br /&gt;
XDocument doc = XDocument.Parse&lt;br /&gt;
(@&amp;quot;&amp;lt;root&amp;gt;&amp;lt;data&amp;gt;hello world&amp;lt;/data&amp;gt;&amp;lt;data&amp;gt;goodbye world&amp;lt;/data&amp;gt;&amp;lt;/root&amp;gt;&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
var results = from data in doc.Descendants(&amp;quot;data&amp;quot;)&lt;br /&gt;
select data;&lt;br /&gt;
&lt;br /&gt;
foreach (var result in results)&lt;br /&gt;
{&lt;br /&gt;
Console.WriteLine(result); 
&lt;br /&gt;
}&lt;br /&gt;
}&lt;/pre&gt;
&lt;p&gt;
The “results” object, by default will be of type “WhereSelectEnumerableIterator” which
exposes a MoveNext() method.&amp;#160; In-fact, that is also why the results object doesn’t
allow you to do something like this:
&lt;/p&gt;
&lt;pre class="c#" name="code"&gt;var results = from data in doc.Descendants(&amp;quot;data&amp;quot;)&lt;br /&gt;
select data;&lt;br /&gt;
&lt;br /&gt;
var bad = results[1];&lt;/pre&gt;
&lt;p&gt;
The IEnumerator does not expose an indexer allowing you to go straight to a particular
element in the collection because the full collection hasn’t been generated yet.&amp;#160;
Instead, you would do something like this:
&lt;/p&gt;
&lt;pre class="c#" name="code"&gt;var results = from data in doc.Descendants(&amp;quot;data&amp;quot;)&lt;br /&gt;
select data; 
&lt;br /&gt;
&lt;br /&gt;
var good = results.ElementAt(1);&lt;/pre&gt;
&lt;p&gt;
And then under the covers, the ElementAt(int) method will just keep calling MoveNext()
until it reaches the index you specified.&amp;#160; Something like this: 
&lt;/p&gt;
&lt;blockquote&gt; 
&lt;p&gt;
&lt;strong&gt;&lt;em&gt;Note:&amp;#160; this is my own code and is NOT from the .NET Framework – it
is merely meant to illustrate a point.&lt;/em&gt;&lt;/strong&gt;
&lt;/p&gt;
&lt;/blockquote&gt; &lt;pre class="c#" name="code"&gt;public static XElement MyElementAt(this IEnumerable&amp;lt;XElement&amp;gt; elements, 
&lt;br /&gt;
int index)&lt;br /&gt;
{&lt;br /&gt;
int counter = 0;&lt;br /&gt;
using (IEnumerator&amp;lt;XElement&amp;gt; enumerator = 
&lt;br /&gt;
elements.GetEnumerator())&lt;br /&gt;
{ 
&lt;br /&gt;
while(enumerator.MoveNext()){&lt;br /&gt;
if (counter == index)&lt;br /&gt;
return enumerator.Current;&lt;br /&gt;
counter++;&lt;br /&gt;
}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
return null;&lt;br /&gt;
}&lt;/pre&gt;
&lt;p&gt;
Hope this helps to demystify some things and put another tool in your toolbox.
&lt;/p&gt;
&lt;p&gt;
Until next time.
&lt;/p&gt;</description>
      <comments>http://www.samuraiprogrammer.com/blog/CommentView,guid,79911823-e816-4166-8552-884b2ea29759.aspx</comments>
      <category>.NET</category>
      <category>Performance</category>
    </item>
    <item>
      <trackback:ping>http://www.samuraiprogrammer.com/blog/Trackback.aspx?guid=d439bf53-49be-4b3d-aaec-02ab63e756f3</trackback:ping>
      <pingback:server>http://www.samuraiprogrammer.com/blog/pingback.aspx</pingback:server>
      <pingback:target>http://www.samuraiprogrammer.com/blog/PermaLink,guid,d439bf53-49be-4b3d-aaec-02ab63e756f3.aspx</pingback:target>
      <dc:creator>Greg Varveris</dc:creator>
      <wfw:comment>http://www.samuraiprogrammer.com/blog/CommentView,guid,d439bf53-49be-4b3d-aaec-02ab63e756f3.aspx</wfw:comment>
      <wfw:commentRss>http://www.samuraiprogrammer.com/blog/SyndicationService.asmx/GetEntryCommentsRss?guid=d439bf53-49be-4b3d-aaec-02ab63e756f3</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
          <a href="http://www.samuraiprogrammer.com/blog/2010/10/04/PivotingASPNETEventLogErrorMessages.aspx">In
my previous post</a>, I added to my series of entries on making sense of your ASP.NET
event log error messages.  Note that this is entry #4 in this series.  The
previous three entries can be found here:
</p>
        <ul>
          <li>
Part 1:  <a href="http://www.samuraiprogrammer.com/blog/ct.ashx?id=a7f8712d-020c-4cd3-acf3-8342ddc1e629&amp;url=http%3a%2f%2fwww.samuraiprogrammer.com%2fblog%2f2010%2f08%2f29%2fParsingASPNETEventLogErrorMessagesForFunAndProfit.aspx">Parsing
ASP.NET event log error messages for fun and profit</a></li>
          <li>
Part 2:  <a href="http://www.samuraiprogrammer.com/blog/ct.ashx?id=a7f8712d-020c-4cd3-acf3-8342ddc1e629&amp;url=http%3a%2f%2fwww.samuraiprogrammer.com%2fblog%2f2010%2f09%2f19%2fDontGuessWhenItComesToPerformanceaRegExStory.aspx">Don’t
guess when it comes to performance…</a></li>
          <li>
Part 3:  <a href="http://www.samuraiprogrammer.com/blog/2010/10/04/PivotingASPNETEventLogErrorMessages.aspx">Pivoting
your ASP.NET event log error messages</a></li>
        </ul>
        <p>
In that last post, I walked through the PAuthorLib.dll and showed you how to crawl
through your event log error messages and create a pivot collection.  The result
of that initial effort was a nice view into our events:
</p>
        <p>
          <a href="http://www.samuraiprogrammer.com/blog/ct.ashx?id=a7f8712d-020c-4cd3-acf3-8342ddc1e629&amp;url=http%3a%2f%2fwww.samuraiprogrammer.com%2fblog%2fcontent%2fbinary%2fWindows-Live-Writer%2f01d5145cc9d9_135BB%2fimage_12.png">
            <img title="image" border="0" alt="image" src="http://www.samuraiprogrammer.com/blog/content/binary/Windows-Live-Writer/01d5145cc9d9_135BB/image_thumb_5.png" width="487" height="377" />
          </a>
        </p>
        <p>
While this certainly got the job done and is a <strong>very </strong>powerful and
compelling view into our data, we need to realize that as our data grow, the amount
of entries in our linked collection is limited.  <a href="http://www.getpivot.com/developer-info/">From
the Developer Overview</a>, we see that the maximum number of items we should have
in a single collection is <strong>3,000</strong>:<strong></strong></p>
        <p>
          <a href="http://www.samuraiprogrammer.com/blog/content/binary/Windows-Live-Writer/Pivoting-ASP.NET_A224/image_6.png">
            <img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://www.samuraiprogrammer.com/blog/content/binary/Windows-Live-Writer/Pivoting-ASP.NET_A224/image_thumb_2.png" width="551" height="320" />
          </a>
        </p>
        <p>
So, while a simple collection will get the job done for your smaller amounts of data,
you will really run into some challenges with your larger datasets like our ASP.NET
event log error messages.  To combat this limitation you can create what’s called
a Linked Collection.  The idea is that it’s just a way for you to link together
related collections in order to provide a seamless experience for your users. 
In our case, a natural break for our collections will be based upon the exception
type with a summary collection and then a separate collection for each exception type. 
If I were to draw this out:  
</p>
        <p>
          <a href="http://www.samuraiprogrammer.com/blog/content/binary/Windows-Live-Writer/Pivoting-ASP.NET_A224/PivotCollections_2.png">
            <img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="PivotCollections" border="0" alt="PivotCollections" src="http://www.samuraiprogrammer.com/blog/content/binary/Windows-Live-Writer/Pivoting-ASP.NET_A224/PivotCollections_thumb.png" width="541" height="204" />
          </a>
        </p>
        <h3>Event Log Header Collection Source
</h3>
        <p>
The idea behind this structure is that the Exception summary would simply link to
each of these exception collections.  First, we’ll create a colleciton source
for our exception summary.  <a href="http://www.samuraiprogrammer.com/blog/2010/10/04/PivotingASPNETEventLogErrorMessages.aspx">As
in our previous collection source (in my last blog post)</a>, we inherit from the
AbstractCollectionSource class and use the LoadHeaderData() method to add our facet
categories to the collection.  In this case, we’ll create two categories – the
number of Occurrences and the Urls where the exception occurred.  Another difference
is that we are going to pass the already parsed collection of messages into the constructor. 
The reason for that is so we don’t have to repeat the parsing of the event log messages
multiple times.
</p>
        <pre class="c#" name="code">class EventLogHeaderCollectionSource : AbstractCollectionSource<br />
{<br /><br />
private IEnumerable&lt;EventLogMessage&gt; m_messages = null;<br /><br />
public EventLogHeaderCollectionSource(IEnumerable&lt;EventLogMessage&gt; messages, 
<br />
string inputFile)<br />
: base(inputFile)<br />
{<br /><br />
m_messages = messages;<br /><br /><br />
}<br /><br />
#region Facets<br /><br />
private const string OCCURRENCES = "Occurrences";<br />
private const string URLS = "Urls";<br /><br />
#endregion<br /><br />
protected override void LoadHeaderData()<br />
{<br />
this.CachedCollectionData.FacetCategories.<br />
Add(new PivotFacetCategory(OCCURRENCES, PivotFacetType.Number));<br />
this.CachedCollectionData.FacetCategories.<br />
Add(new PivotFacetCategory(URLS, PivotFacetType.String));<br /><br />
this.CachedCollectionData.Name = 
<br />
"ASP.NET Error Messages - Summary";<br />
this.CachedCollectionData.Copyright = 
<br />
new PivotLink("Source", "http://www.samuraiprogrammer.com");<br /><br />
}<br />
}</pre>
        <p>
Then, in the LoadItems() method, we provide the logic to generate the PivotItem collection. 
The one key item to make note of is the use of the <strong>Href </strong>property
of the PivotItem object.  This is where we specify the collection we wish to
link to this item.  Since each of the PivotItems will be a summary of the number
of each exception type – we’ll name the sub-collections by its exception type. 
For example, NullReferenceException.cxml, SqlException.cxml, etc.
</p>
        <pre class="c#" name="code">protected override IEnumerable&lt;PivotItem&gt; LoadItems()<br />
{<br />
var results = from log in m_messages<br />
group log by log.Exceptiontype into l<br />
orderby l.Count() descending, l.Key<br />
select new<br />
{<br />
ExceptionType = l.Key,<br />
ExceptionCount = l.Count()<br />
};<br /><br /><br />
int index = 0;<br />
foreach (var result in results)<br />
{<br />
PivotItem item = new PivotItem(index.ToString(), this); 
<br />
item.Name = result.ExceptionType;<br />
item.Description = "# of Exceptions: " + result.ExceptionCount.ToString();<br />
item.AddFacetValues(OCCURRENCES, result.ExceptionCount);<br />
item.Href = result.ExceptionType + ".cxml";<br /><br />
... 
<br /><br />
index++;<br />
yield return item;<br />
}<br /><br />
yield break;<br />
}</pre>
        <h3>Event Log Collection Source Redux
</h3>
        <p>
Previously, when we generated the pivot collections, we were outputting all of the
records into a single collection.  Now that we are generating a collection for
each exception type, we will need to put a filter in our exception collection and
then incorporate that filter into our item generation.  Other than that, the
code we wrote previously remains largely unchanged, so I left the majority of it out
and only included the snippets that we care about below.
</p>
        <pre class="c#" name="code">class EventLogCollectionSource : AbstractCollectionSource<br />
{<br />
private IEnumerable&lt;EventLogMessage&gt; m_messages = null;<br />
private string m_exceptionType = string.Empty;<br /><br />
public EventLogCollectionSource(<br />
IEnumerable&lt;EventLogMessage&gt; messages, 
<br />
string exceptionType, 
<br />
string path)<br />
: base(path)<br />
{<br />
m_messages = messages;<br />
m_exceptionType = exceptionType;<br />
}<br /><br />
protected override void LoadHeaderData()<br />
{<br />
...<br />
this.CachedCollectionData.Name = 
<br />
string.Format("{0} Error Messages", m_exceptionType);<br />
...<br />
}<br /><br />
protected override IEnumerable&lt;PivotItem&gt; LoadItems()<br />
{<br />
var results = (from message in m_messages<br />
where message.Exceptiontype == m_exceptionType<br />
select message);<br /><br />
int index = 0;<br />
foreach (EventLogMessage message in results)<br />
{<br />
PivotItem item = 
<br />
new PivotItem(index.ToString(), this);<br />
item.Name = message.Exceptiontype;<br />
item.Description = message.Exceptionmessage;<br /><br />
...<br /><br />
index++;<br />
yield return item;<br />
}<br />
yield break;<br />
}<br />
}</pre>
        <h3>Generate and test the collection
</h3>
        <p>
Then, the only thing we have left to do is generate and test our linked collections. 
I won’t go into a lengthy explanation of how we generate the collections because <a href="http://www.samuraiprogrammer.com/blog/2010/10/04/PivotingASPNETEventLogErrorMessages.aspx">I
did that in the last blog entry</a>.  I will show the broad strokes required
to tie this all together, though:
</p>
        <pre class="c#" name="code">// Load the raw messages into a collection<br />
IEnumerable&lt;EventLogMessage&gt; messages = 
<br />
LoadEventLogMessages(inputFile).ToList();<br /><br />
// Generate summary pivot collection<br />
EventLogHeaderCollectionSource sourceSummary = 
<br />
new EventLogHeaderCollectionSource(messages, inputFile);<br />
...<br />
summaryTargetFilter1.Write(sourceSummaryFilter1);<br /><br />
// Get the aggregate results so we know the filters<br />
// for our exception pivot collections<br />
var summaryResults = from log in messages<br />
group log by log.Exceptiontype into l<br />
orderby l.Count() descending, l.Key<br />
select new<br />
{<br />
ExceptionType = l.Key,<br />
ExceptionCount = l.Count()<br />
};<br /><br />
foreach (var resultItem in summaryResults)<br />
{<br />
// Generate pivots for each exception type<br />
EventLogCollectionSource source = 
<br />
new EventLogCollectionSource(messages, 
<br />
resultItem.ExceptionType, 
<br />
inputFile);<br />
...<br />
targetFilter1.Write(sourceFilter1);<br />
}</pre>
        <p>
Once we we have this code and everything has been generated, if we open the output
folder, we’ll see the following structure:
</p>
        <p>
          <a href="http://www.samuraiprogrammer.com/blog/content/binary/Windows-Live-Writer/Pivoting-ASP.NET_A224/image_8.png">
            <img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://www.samuraiprogrammer.com/blog/content/binary/Windows-Live-Writer/Pivoting-ASP.NET_A224/image_thumb_3.png" width="515" height="387" />
          </a>
        </p>
        <p>
We see our ExceptionSummary pivot collection and all of the deep zoom folders. 
So, when we open the Pivot tool, we’ll see a nice parent collection:
</p>
        <p>
          <a href="http://www.samuraiprogrammer.com/blog/content/binary/Windows-Live-Writer/Pivoting-ASP.NET_A224/image_10.png">
            <img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://www.samuraiprogrammer.com/blog/content/binary/Windows-Live-Writer/Pivoting-ASP.NET_A224/image_thumb_4.png" width="644" height="407" />
          </a>
        </p>
        <p>
This gives us a nice breakdown of the number of occurrences for each exception in
our source data.  Immediately we see an outlier (more on that later) between
the 6,000 and 7,000 item mark and when we select that tile, we see the following:
</p>
        <p>
          <a href="http://www.samuraiprogrammer.com/blog/content/binary/Windows-Live-Writer/Pivoting-ASP.NET_A224/image_12.png">
            <img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://www.samuraiprogrammer.com/blog/content/binary/Windows-Live-Writer/Pivoting-ASP.NET_A224/image_thumb_5.png" width="644" height="440" />
          </a>
        </p>
        <p>
We also see a green “Open” box (surrounded in a red rectangle, my emphasis) which
links to our NullReferenceException.cxml.  When we click that box, the tool will
immediately open that collection in the UI for our perusal – providing a very similar
look to what we saw in the last entry:
</p>
        <p>
          <a href="http://www.samuraiprogrammer.com/blog/content/binary/Windows-Live-Writer/Pivoting-ASP.NET_A224/image_14.png">
            <img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://www.samuraiprogrammer.com/blog/content/binary/Windows-Live-Writer/Pivoting-ASP.NET_A224/image_thumb_6.png" width="644" height="377" />
          </a>
        </p>
        <h3>Closing Thoughts
</h3>
        <p>
Now, you may have noticed a contradiction above.  I said that a collection should
have no more than 3,000 items and yet, with the NullReferenceException collection,
we saw in the summary that it had over 6,000 items.  That is a very good point
and will be a subject of a future blog post.  I wanted to illustrate the simple
collections and the linked collections before we got into that third type of collection
from above – the Dynamic Collection.  Stay tuned!
</p>
      </body>
      <title>Linking your pivot collections the fun and easy way</title>
      <guid isPermaLink="false">http://www.samuraiprogrammer.com/blog/PermaLink,guid,d439bf53-49be-4b3d-aaec-02ab63e756f3.aspx</guid>
      <link>http://www.samuraiprogrammer.com/blog/2010/10/11/LinkingYourPivotCollectionsTheFunAndEasyWay.aspx</link>
      <pubDate>Mon, 11 Oct 2010 05:09:42 GMT</pubDate>
      <description>&lt;p&gt;
&lt;a href="http://www.samuraiprogrammer.com/blog/2010/10/04/PivotingASPNETEventLogErrorMessages.aspx"&gt;In
my previous post&lt;/a&gt;, I added to my series of entries on making sense of your ASP.NET
event log error messages.&amp;#160; Note that this is entry #4 in this series.&amp;#160; The
previous three entries can be found here:
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
Part 1:&amp;#160; &lt;a href="http://www.samuraiprogrammer.com/blog/ct.ashx?id=a7f8712d-020c-4cd3-acf3-8342ddc1e629&amp;amp;url=http%3a%2f%2fwww.samuraiprogrammer.com%2fblog%2f2010%2f08%2f29%2fParsingASPNETEventLogErrorMessagesForFunAndProfit.aspx"&gt;Parsing
ASP.NET event log error messages for fun and profit&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
Part 2:&amp;#160; &lt;a href="http://www.samuraiprogrammer.com/blog/ct.ashx?id=a7f8712d-020c-4cd3-acf3-8342ddc1e629&amp;amp;url=http%3a%2f%2fwww.samuraiprogrammer.com%2fblog%2f2010%2f09%2f19%2fDontGuessWhenItComesToPerformanceaRegExStory.aspx"&gt;Don’t
guess when it comes to performance…&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
Part 3:&amp;#160; &lt;a href="http://www.samuraiprogrammer.com/blog/2010/10/04/PivotingASPNETEventLogErrorMessages.aspx"&gt;Pivoting
your ASP.NET event log error messages&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
In that last post, I walked through the PAuthorLib.dll and showed you how to crawl
through your event log error messages and create a pivot collection.&amp;#160; The result
of that initial effort was a nice view into our events:
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://www.samuraiprogrammer.com/blog/ct.ashx?id=a7f8712d-020c-4cd3-acf3-8342ddc1e629&amp;amp;url=http%3a%2f%2fwww.samuraiprogrammer.com%2fblog%2fcontent%2fbinary%2fWindows-Live-Writer%2f01d5145cc9d9_135BB%2fimage_12.png"&gt;&lt;img title="image" border="0" alt="image" src="http://www.samuraiprogrammer.com/blog/content/binary/Windows-Live-Writer/01d5145cc9d9_135BB/image_thumb_5.png" width="487" height="377" /&gt;&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;
While this certainly got the job done and is a &lt;strong&gt;very &lt;/strong&gt;powerful and
compelling view into our data, we need to realize that as our data grow, the amount
of entries in our linked collection is limited.&amp;#160; &lt;a href="http://www.getpivot.com/developer-info/"&gt;From
the Developer Overview&lt;/a&gt;, we see that the maximum number of items we should have
in a single collection is &lt;strong&gt;3,000&lt;/strong&gt;:&lt;strong&gt; &lt;/strong&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://www.samuraiprogrammer.com/blog/content/binary/Windows-Live-Writer/Pivoting-ASP.NET_A224/image_6.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://www.samuraiprogrammer.com/blog/content/binary/Windows-Live-Writer/Pivoting-ASP.NET_A224/image_thumb_2.png" width="551" height="320" /&gt;&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;
So, while a simple collection will get the job done for your smaller amounts of data,
you will really run into some challenges with your larger datasets like our ASP.NET
event log error messages.&amp;#160; To combat this limitation you can create what’s called
a Linked Collection.&amp;#160; The idea is that it’s just a way for you to link together
related collections in order to provide a seamless experience for your users.&amp;#160;
In our case, a natural break for our collections will be based upon the exception
type with a summary collection and then a separate collection for each exception type.&amp;#160;
If I were to draw this out:&amp;#160; 
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://www.samuraiprogrammer.com/blog/content/binary/Windows-Live-Writer/Pivoting-ASP.NET_A224/PivotCollections_2.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="PivotCollections" border="0" alt="PivotCollections" src="http://www.samuraiprogrammer.com/blog/content/binary/Windows-Live-Writer/Pivoting-ASP.NET_A224/PivotCollections_thumb.png" width="541" height="204" /&gt;&lt;/a&gt;
&lt;/p&gt;
&lt;h3&gt;Event Log Header Collection Source
&lt;/h3&gt;
&lt;p&gt;
The idea behind this structure is that the Exception summary would simply link to
each of these exception collections.&amp;#160; First, we’ll create a colleciton source
for our exception summary.&amp;#160; &lt;a href="http://www.samuraiprogrammer.com/blog/2010/10/04/PivotingASPNETEventLogErrorMessages.aspx"&gt;As
in our previous collection source (in my last blog post)&lt;/a&gt;, we inherit from the
AbstractCollectionSource class and use the LoadHeaderData() method to add our facet
categories to the collection.&amp;#160; In this case, we’ll create two categories – the
number of Occurrences and the Urls where the exception occurred.&amp;#160; Another difference
is that we are going to pass the already parsed collection of messages into the constructor.&amp;#160;
The reason for that is so we don’t have to repeat the parsing of the event log messages
multiple times.
&lt;/p&gt;
&lt;pre class="c#" name="code"&gt;class EventLogHeaderCollectionSource : AbstractCollectionSource&lt;br /&gt;
{&lt;br /&gt;
&lt;br /&gt;
private IEnumerable&amp;lt;EventLogMessage&amp;gt; m_messages = null;&lt;br /&gt;
&lt;br /&gt;
public EventLogHeaderCollectionSource(IEnumerable&amp;lt;EventLogMessage&amp;gt; messages, 
&lt;br /&gt;
string inputFile)&lt;br /&gt;
: base(inputFile)&lt;br /&gt;
{&lt;br /&gt;
&lt;br /&gt;
m_messages = messages;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#region Facets&lt;br /&gt;
&lt;br /&gt;
private const string OCCURRENCES = &amp;quot;Occurrences&amp;quot;;&lt;br /&gt;
private const string URLS = &amp;quot;Urls&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
#endregion&lt;br /&gt;
&lt;br /&gt;
protected override void LoadHeaderData()&lt;br /&gt;
{&lt;br /&gt;
this.CachedCollectionData.FacetCategories.&lt;br /&gt;
Add(new PivotFacetCategory(OCCURRENCES, PivotFacetType.Number));&lt;br /&gt;
this.CachedCollectionData.FacetCategories.&lt;br /&gt;
Add(new PivotFacetCategory(URLS, PivotFacetType.String));&lt;br /&gt;
&lt;br /&gt;
this.CachedCollectionData.Name = 
&lt;br /&gt;
&amp;quot;ASP.NET Error Messages - Summary&amp;quot;;&lt;br /&gt;
this.CachedCollectionData.Copyright = 
&lt;br /&gt;
new PivotLink(&amp;quot;Source&amp;quot;, &amp;quot;http://www.samuraiprogrammer.com&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
}&lt;/pre&gt;
&lt;p&gt;
Then, in the LoadItems() method, we provide the logic to generate the PivotItem collection.&amp;#160;
The one key item to make note of is the use of the &lt;strong&gt;Href &lt;/strong&gt;property
of the PivotItem object.&amp;#160; This is where we specify the collection we wish to
link to this item.&amp;#160; Since each of the PivotItems will be a summary of the number
of each exception type – we’ll name the sub-collections by its exception type.&amp;#160;
For example, NullReferenceException.cxml, SqlException.cxml, etc.
&lt;/p&gt;
&lt;pre class="c#" name="code"&gt;protected override IEnumerable&amp;lt;PivotItem&amp;gt; LoadItems()&lt;br /&gt;
{&lt;br /&gt;
var results = from log in m_messages&lt;br /&gt;
group log by log.Exceptiontype into l&lt;br /&gt;
orderby l.Count() descending, l.Key&lt;br /&gt;
select new&lt;br /&gt;
{&lt;br /&gt;
ExceptionType = l.Key,&lt;br /&gt;
ExceptionCount = l.Count()&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
int index = 0;&lt;br /&gt;
foreach (var result in results)&lt;br /&gt;
{&lt;br /&gt;
PivotItem item = new PivotItem(index.ToString(), this); 
&lt;br /&gt;
item.Name = result.ExceptionType;&lt;br /&gt;
item.Description = &amp;quot;# of Exceptions: &amp;quot; + result.ExceptionCount.ToString();&lt;br /&gt;
item.AddFacetValues(OCCURRENCES, result.ExceptionCount);&lt;br /&gt;
item.Href = result.ExceptionType + &amp;quot;.cxml&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
... 
&lt;br /&gt;
&lt;br /&gt;
index++;&lt;br /&gt;
yield return item;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
yield break;&lt;br /&gt;
}&lt;/pre&gt;
&lt;h3&gt;Event Log Collection Source Redux
&lt;/h3&gt;
&lt;p&gt;
Previously, when we generated the pivot collections, we were outputting all of the
records into a single collection.&amp;#160; Now that we are generating a collection for
each exception type, we will need to put a filter in our exception collection and
then incorporate that filter into our item generation.&amp;#160; Other than that, the
code we wrote previously remains largely unchanged, so I left the majority of it out
and only included the snippets that we care about below.
&lt;/p&gt;
&lt;pre class="c#" name="code"&gt;class EventLogCollectionSource : AbstractCollectionSource&lt;br /&gt;
{&lt;br /&gt;
private IEnumerable&amp;lt;EventLogMessage&amp;gt; m_messages = null;&lt;br /&gt;
private string m_exceptionType = string.Empty;&lt;br /&gt;
&lt;br /&gt;
public EventLogCollectionSource(&lt;br /&gt;
IEnumerable&amp;lt;EventLogMessage&amp;gt; messages, 
&lt;br /&gt;
string exceptionType, 
&lt;br /&gt;
string path)&lt;br /&gt;
: base(path)&lt;br /&gt;
{&lt;br /&gt;
m_messages = messages;&lt;br /&gt;
m_exceptionType = exceptionType;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
protected override void LoadHeaderData()&lt;br /&gt;
{&lt;br /&gt;
...&lt;br /&gt;
this.CachedCollectionData.Name = 
&lt;br /&gt;
string.Format(&amp;quot;{0} Error Messages&amp;quot;, m_exceptionType);&lt;br /&gt;
...&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
protected override IEnumerable&amp;lt;PivotItem&amp;gt; LoadItems()&lt;br /&gt;
{&lt;br /&gt;
var results = (from message in m_messages&lt;br /&gt;
where message.Exceptiontype == m_exceptionType&lt;br /&gt;
select message);&lt;br /&gt;
&lt;br /&gt;
int index = 0;&lt;br /&gt;
foreach (EventLogMessage message in results)&lt;br /&gt;
{&lt;br /&gt;
PivotItem item = 
&lt;br /&gt;
new PivotItem(index.ToString(), this);&lt;br /&gt;
item.Name = message.Exceptiontype;&lt;br /&gt;
item.Description = message.Exceptionmessage;&lt;br /&gt;
&lt;br /&gt;
...&lt;br /&gt;
&lt;br /&gt;
index++;&lt;br /&gt;
yield return item;&lt;br /&gt;
}&lt;br /&gt;
yield break;&lt;br /&gt;
}&lt;br /&gt;
}&lt;/pre&gt;
&lt;h3&gt;Generate and test the collection
&lt;/h3&gt;
&lt;p&gt;
Then, the only thing we have left to do is generate and test our linked collections.&amp;#160;
I won’t go into a lengthy explanation of how we generate the collections because &lt;a href="http://www.samuraiprogrammer.com/blog/2010/10/04/PivotingASPNETEventLogErrorMessages.aspx"&gt;I
did that in the last blog entry&lt;/a&gt;.&amp;#160; I will show the broad strokes required
to tie this all together, though:
&lt;/p&gt;
&lt;pre class="c#" name="code"&gt;// Load the raw messages into a collection&lt;br /&gt;
IEnumerable&amp;lt;EventLogMessage&amp;gt; messages = 
&lt;br /&gt;
LoadEventLogMessages(inputFile).ToList();&lt;br /&gt;
&lt;br /&gt;
// Generate summary pivot collection&lt;br /&gt;
EventLogHeaderCollectionSource sourceSummary = 
&lt;br /&gt;
new EventLogHeaderCollectionSource(messages, inputFile);&lt;br /&gt;
...&lt;br /&gt;
summaryTargetFilter1.Write(sourceSummaryFilter1);&lt;br /&gt;
&lt;br /&gt;
// Get the aggregate results so we know the filters&lt;br /&gt;
// for our exception pivot collections&lt;br /&gt;
var summaryResults = from log in messages&lt;br /&gt;
group log by log.Exceptiontype into l&lt;br /&gt;
orderby l.Count() descending, l.Key&lt;br /&gt;
select new&lt;br /&gt;
{&lt;br /&gt;
ExceptionType = l.Key,&lt;br /&gt;
ExceptionCount = l.Count()&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
foreach (var resultItem in summaryResults)&lt;br /&gt;
{&lt;br /&gt;
// Generate pivots for each exception type&lt;br /&gt;
EventLogCollectionSource source = 
&lt;br /&gt;
new EventLogCollectionSource(messages, 
&lt;br /&gt;
resultItem.ExceptionType, 
&lt;br /&gt;
inputFile);&lt;br /&gt;
...&lt;br /&gt;
targetFilter1.Write(sourceFilter1);&lt;br /&gt;
}&lt;/pre&gt;
&lt;p&gt;
Once we we have this code and everything has been generated, if we open the output
folder, we’ll see the following structure:
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://www.samuraiprogrammer.com/blog/content/binary/Windows-Live-Writer/Pivoting-ASP.NET_A224/image_8.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://www.samuraiprogrammer.com/blog/content/binary/Windows-Live-Writer/Pivoting-ASP.NET_A224/image_thumb_3.png" width="515" height="387" /&gt;&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;
We see our ExceptionSummary pivot collection and all of the deep zoom folders.&amp;#160;
So, when we open the Pivot tool, we’ll see a nice parent collection:
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://www.samuraiprogrammer.com/blog/content/binary/Windows-Live-Writer/Pivoting-ASP.NET_A224/image_10.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://www.samuraiprogrammer.com/blog/content/binary/Windows-Live-Writer/Pivoting-ASP.NET_A224/image_thumb_4.png" width="644" height="407" /&gt;&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;
This gives us a nice breakdown of the number of occurrences for each exception in
our source data.&amp;#160; Immediately we see an outlier (more on that later) between
the 6,000 and 7,000 item mark and when we select that tile, we see the following:
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://www.samuraiprogrammer.com/blog/content/binary/Windows-Live-Writer/Pivoting-ASP.NET_A224/image_12.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://www.samuraiprogrammer.com/blog/content/binary/Windows-Live-Writer/Pivoting-ASP.NET_A224/image_thumb_5.png" width="644" height="440" /&gt;&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;
We also see a green “Open” box (surrounded in a red rectangle, my emphasis) which
links to our NullReferenceException.cxml.&amp;#160; When we click that box, the tool will
immediately open that collection in the UI for our perusal – providing a very similar
look to what we saw in the last entry:
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://www.samuraiprogrammer.com/blog/content/binary/Windows-Live-Writer/Pivoting-ASP.NET_A224/image_14.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://www.samuraiprogrammer.com/blog/content/binary/Windows-Live-Writer/Pivoting-ASP.NET_A224/image_thumb_6.png" width="644" height="377" /&gt;&lt;/a&gt;
&lt;/p&gt;
&lt;h3&gt;Closing Thoughts
&lt;/h3&gt;
&lt;p&gt;
Now, you may have noticed a contradiction above.&amp;#160; I said that a collection should
have no more than 3,000 items and yet, with the NullReferenceException collection,
we saw in the summary that it had over 6,000 items.&amp;#160; That is a very good point
and will be a subject of a future blog post.&amp;#160; I wanted to illustrate the simple
collections and the linked collections before we got into that third type of collection
from above – the Dynamic Collection.&amp;#160; Stay tuned!
&lt;/p&gt;</description>
      <comments>http://www.samuraiprogrammer.com/blog/CommentView,guid,d439bf53-49be-4b3d-aaec-02ab63e756f3.aspx</comments>
      <category>ASP.NET</category>
      <category>Development</category>
      <category>Pivot</category>
    </item>
  </channel>
</rss>