<?xml version="1.0" encoding="utf-8"?>
<rss xmlns:atom="http://www.w3.org/2005/Atom" xmlns:sy="http://purl.org/rss/1.0/modules/syndication/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
  version="2.0">
  <channel>
    <title>Pigs Can Fly</title>
    <atom:link
      href="https://docs.microsoft.com/archive/blogs/pigscanfly/feed.xml"
      rel="self"
      type="application/rss+xml" />
    <link>https://docs.microsoft.com/archive/blogs/pigscanfly/feed.xml</link>
    <description>Windows performance, development, and related issues(and maybe some not so related...)</description>
    <lastBuildDate>Thu, 09 Apr 2015 19:33:28 GMT</lastBuildDate>
    <language>en-US</language>
    <sy:updatePeriod>hourly</sy:updatePeriod>
    <sy:updateFrequency>1</sy:updateFrequency>
    <item>
      <title>C# IShellLink COM Interop Example #1</title>
      <link>https://docs.microsoft.com/archive/blogs/pigscanfly/c-ishelllink-com-interop-example-1</link>
      <pubDate>Sun, 05 Dec 2010 09:28:07 GMT</pubDate>
      <dc:creator><![CDATA[rgr]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/pigscanfly/2010/12/05/c-ishelllink-com-interop-example-1/</guid>
      <description><![CDATA[I recently needed to use C# to programmatically create a shortcut (.LNK file) to a console...]]></description>
      <content:encoded><![CDATA[<p>I recently needed to use C# to programmatically create a shortcut (.LNK file) to a console executable. This is easily done in native C/C++ using the <a href="http://msdn.microsoft.com/en-us/library/bb776891(VS.85).aspx" target="_blank">ShellLink CoClass</a>, the <a href="http://msdn.microsoft.com/en-us/library/bb774950(VS.85).aspx" target="_blank">IShellLink</a> interface and their related interfaces.</p>  <p>I looked around and couldn’t find a good C# COM interop example for the related native COM interfaces so I wrote one.&#160;&#160; This was a good excuse for me to learn a litle bit about C# and COM interoperability.&#160; You can find the source code <a title="Download" href="http://cid-5424e22be0b9172a.office.live.com/self.aspx/BlogPostAttachments/ShellLinkExperiments-1-Setup.exe" target="_blank">here</a>, provided under the <a href="http://msdn.microsoft.com/en-us/windowsmobile/bb264332.aspx" target="_blank">Microsoft Permissive License</a>.</p>  <p>This first cut provides a set of C# classes and related values for manipulating <a href="http://msdn.microsoft.com/en-us/library/bb776891(VS.85).aspx" target="_blank">Windows Shell Links</a>.&#160; The public methods, properties and enumerations (or just publics) are C# style – I didn’t let the underlying native names leak through.&#160; </p>  <p>For example, an important native enumeration is the native <a href="http://msdn.microsoft.com/en-us/library/bb762540(VS.85).aspx" target="_blank">SHELL_LINK_DATA_FLAGS</a> enumeration.&#160;&#160; I’ve seen some interop examples that expose the native names of things publicly in C#.&#160;&#160; This works, but doesn’t follow the .<a href="http://msdn.microsoft.com/en-us/library/czefa0ke(VS.71).aspx" target="_blank">NET Design Guidelines for Class Library Developers</a> (<a href="http://www.amazon.com/Framework-Design-Guidelines-Conventions-Libraries/dp/0321545613/ref=sr_1_1?ie=UTF8&amp;s=books&amp;qid=1290977476&amp;sr=8-1" target="_blank">in hardback on Amazon</a>).&#160;&#160; Exposing the native names is a bit ugly in .NET languages, and in C# in particular.&#160; </p>  <p>In the public aspects of my C# I provide the native functionally in a modern C# manner.&#160; For example, I&#160; provide a .NET enuneration named ShellLinkFlags which provides the values in SHELL_LINK_DATA_FLAGS.&#160;&#160; These enumerations have C# style names like <strong>RunAsUser</strong> instead of <strong>SLDF_RUNAS_USER</strong>.</p>  <p>Another important attribute is that all of the publics are <a href="http://msdn.microsoft.com/en-us/library/bhc3fa7f.aspx" target="_blank">CLS compliant</a>.&#160; This enables all .NET languages to easily access these classes, not just C#. </p>  <p>There are some limitations to this code.&#160; I built this so I could create shell links to EXEs – primarily console applications.&#160;&#160;&#160; This code does not yet support the IShellLink.GetIDList() and IShellLInk.SetIDList() methiods.&#160; So, it can only be used to link to things in the file system, and not shell objects such as printers.</p>  <h2></h2>  <h4>The Project</h4>  <p>This code is provided in a Visual Studio 2010 project built with C# and .NET 4.0 using the client profile.</p>  <p>The actual shell interop code is built in a separate class library named <strong>Eidos</strong>, which is the name of my general purpose C# library.&#160;&#160; The namespace is <strong>Eidos.Shell</strong>.&#160;&#160; You can use this directly, or easily incorporate it into your own code. </p>  <p>I’ve also included a couple of basic unit tests – you can extend these as needed. </p>  <p>There is also a simple program that will dump the contents of a Shell link file to the console.</p>  <h4>The Code</h4>  <p>The primary public class is <strong>ShellLink</strong>.&#160; This provides a set of properties and methods that provides the functionality of IShellLink but in a C# manner. </p>  <p>One of the biggest differences between the C# APIs and the native COM interfaces are how Data Blocks and IShellLinkDataList are treated.&#160;&#160;&#160; These are not exposed in the my .NET classes.&#160; instead, they are wrapped using standard properties on the C# ShellLink class.</p>  <p>This works really well.&#160; It means you can simply get and set property values just like you would with a “normal” .NET class.&#160;&#160; The IShellLink class handles all the work of creating, writing and reading the data blocks using an internal IShellLinkDataList interface. </p>  <h4>Download the Source</h4>  <p>You can find the source code <a title="Download" href="http://cid-5424e22be0b9172a.office.live.com/self.aspx/BlogPostAttachments/ShellLinkExperiments-1-Setup.exe" target="_blank"><strong>here</strong></a>, provided under the <a href="http://msdn.microsoft.com/en-us/windowsmobile/bb264332.aspx" target="_blank">Microsoft Permissive License</a>.</p>]]></content:encoded>
    </item>
    <item>
      <title>WPF: Styling the Expander Control</title>
      <link>https://docs.microsoft.com/archive/blogs/pigscanfly/wpf-styling-the-expander-control</link>
      <pubDate>Sun, 28 Mar 2010 10:49:10 GMT</pubDate>
      <dc:creator><![CDATA[rgr]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/pigscanfly/2010/03/28/wpf-styling-the-expander-control/</guid>
      <description><![CDATA[I recently needed to style a WPF expander control for a prototype project. Our team’s UX designer...]]></description>
      <content:encoded><![CDATA[<p>I recently needed to style a WPF expander control for a prototype project. Our team’s UX designer came up with a nice visual design.&#160;&#160;&#160; So, I began to build my prototype and match his visual style (mocked up in Visio) in WPF.&#160;&#160; I thought it would be easy…&#160;&#160; it was, once I spent all morning&#160; figuring out how to do it…</p>  <p>Here is screen shot of the prototype – it is pretty close to the mock up.</p>  <p><a href="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/BlogFileStorage/blogs_msdn/pigscanfly/WindowsLiveWriter/WPFStylingtheExpanderControl_78C3/ScreenShot1_4.png" original-url="http://blogs.msdn.com/blogfiles/pigscanfly/WindowsLiveWriter/WPFStylingtheExpanderControl_78C3/ScreenShot1_4.png"><img style="border-right-width: 0px; display: block; float: none; border-top-width: 0px; border-bottom-width: 0px; margin-left: auto; border-left-width: 0px; margin-right: auto" title="ScreenShot1" border="0" alt="ScreenShot1" src="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/BlogFileStorage/blogs_msdn/pigscanfly/WindowsLiveWriter/WPFStylingtheExpanderControl_78C3/ScreenShot1_thumb_1.png" original-url="http://blogs.msdn.com/blogfiles/pigscanfly/WindowsLiveWriter/WPFStylingtheExpanderControl_78C3/ScreenShot1_thumb_1.png" width="694" height="417" /></a> </p>  <p>I started off with the <a href="http://msdn.microsoft.com/en-us/library/ms753296.aspx" target="_blank">Expander Control Template example on MSDN</a>.&#160; This wasn’t a bad start – it showed me how to change expander toggle button – nice.</p>  <p>But, I also needed to change the font used in the expander header.&#160; That wasn’t shown in the example.&#160;&#160; Ok, no problem – just use a setter in the style like this - right?&#160; </p>  <pre class="code">    <span style="color: blue">&lt;</span><span style="color: #a31515">Style </span><span style="color: red">x</span><span style="color: blue">:</span><span style="color: red">Key</span><span style="color: blue">=&quot;MainViewExpander&quot; </span><span style="color: red">TargetType</span><span style="color: blue">=&quot;Expander&quot;&gt;
        &lt;</span><span style="color: #a31515">Setter </span><span style="color: red">Property</span><span style="color: blue">=&quot;FontSize&quot; </span><span style="color: red">Value</span><span style="color: blue">=&quot;18&quot; /&gt;
        &lt;</span><span style="color: #a31515">Setter </span><span style="color: red">Property</span><span style="color: blue">=&quot;FontWeight&quot; </span><span style="color: red">Value</span><span style="color: blue">=&quot;Bold&quot; /&gt;
        &lt;</span><span style="color: #a31515">Setter </span><span style="color: red">Property</span><span style="color: blue">=&quot;Template&quot;&gt;
            &lt;</span><span style="color: #a31515">Setter.Value</span><span style="color: blue">&gt;
                &lt;</span><span style="color: #a31515">ControlTemplate </span><span style="color: red">TargetType</span><span style="color: blue">=&quot;Expander&quot;&gt;
</span></pre>
<a href="http://11011.net/software/vspaste"></a>

<p>&#160;</p>

<p><a href="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/BlogFileStorage/blogs_msdn/pigscanfly/WindowsLiveWriter/WPFStylingtheExpanderControl_78C3/Example1_2.png" original-url="http://blogs.msdn.com/blogfiles/pigscanfly/WindowsLiveWriter/WPFStylingtheExpanderControl_78C3/Example1_2.png"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; margin-left: 0px; border-left-width: 0px; margin-right: 0px" title="Example1" border="0" alt="Example1" align="right" src="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/BlogFileStorage/blogs_msdn/pigscanfly/WindowsLiveWriter/WPFStylingtheExpanderControl_78C3/Example1_thumb.png" original-url="http://blogs.msdn.com/blogfiles/pigscanfly/WindowsLiveWriter/WPFStylingtheExpanderControl_78C3/Example1_thumb.png" width="309" height="259" /></a>Bzzzztttt… wrong.&#160;&#160; That set the font appearance in the Expander header like I wanted, but all the controls in the Expander content property inherited the font appearance.&#160; That’s not what I wanted at all.</p>

<p>I needed to style the appearance of the Expander header and its contents separately. </p>

<p>So, i dug around in MSDN a little more.&#160; The key information turned out to be in the documentation for the <a href="http://msdn.microsoft.com/en-us/library/system.windows.controls.headeredcontentcontrol.aspx" target="_blank">Headered Content Control class</a>.&#160;&#160; </p>

<p>This is an important class as it defines the base functionality for controls including the Expander, Group Box and TabItem controls – all very commonly used controls.</p>

<p>They key to getting the look I wanted is using <a href="http://msdn.microsoft.com/en-us/library/ms742521.aspx" target="_blank">Data Templates</a>.&#160;&#160; I’ve seen this used in many MSDN examples and WPF blog posts but until now, I never really understood them. </p>

<p>In short, data templates are like control templates but instead of defining how WPF structures the visual tree for a control, data template defines how WPF displays data.&#160; </p>

<p>We’ll, you might say “Duh Richard!”&#160; That’s what the docs say….&#160; Ya, Duh! For sure…&#160; I didn’t <a href="http://www.merriam-webster.com/dictionary/grok" target="_blank">grok</a> exactly what this meant until now: they key for me was finally understanding that the data template is bound to the data it is intended to display. </p>

<p>All data template intentions are bound to a property on an object instance.&#160;&#160; You can refer to this binding by using the simple most binding which is <span style="color: blue">&quot;{</span><span style="color: #a31515">Binding</span><span style="color: blue">}&quot;</span>.&#160; You can see how this is used below.</p>

<p>The key is that all Headered Content Controls have a data template for the header content.&#160;&#160;&#160; So, setting the font appearance for the Expander header was a simple matter of adding this setter to my style</p>

<pre class="code">&#160;</pre>

<pre class="code">        <span style="color: blue">&lt;</span><span style="color: #a31515">Setter </span><span style="color: red">Property</span><span style="color: blue">=&quot;HeaderTemplate&quot;&gt;
            &lt;</span><span style="color: #a31515">Setter.Value</span><span style="color: blue">&gt;
                &lt;</span><span style="color: #a31515">DataTemplate</span><span style="color: blue">&gt;
                    &lt;</span><span style="color: #a31515">TextBlock 
                        </span><font size="4"><strong><span style="color: red">Text</span><span style="color: blue">=&quot;{</span><span style="color: #a31515">Binding</span></strong></font><span style="color: blue"><font size="4"><strong>}&quot;</strong></font> 
                        </span><span style="color: red">FontSize</span><span style="color: blue">=&quot;18&quot; 
                        </span><span style="color: red">FontWeight</span><span style="color: blue">=&quot;Bold&quot;
                        </span><span style="color: red">Foreground</span><span style="color: blue">=&quot;White&quot;
                        /&gt;
                &lt;/</span><span style="color: #a31515">DataTemplate</span><span style="color: blue">&gt;
            &lt;/</span><span style="color: #a31515">Setter.Value</span><span style="color: blue">&gt;
        &lt;/</span><span style="color: #a31515">Setter</span><span style="color: blue">&gt;
</span></pre>
<a href="http://11011.net/software/vspaste"></a>

<p><a href="http://11011.net/software/vspaste"></a>&#160;</p>

<p>This worked great!&#160; As you can see in the screen shot at the beginning of the post, I set the text appearance to the white, 18 size bold text I wanted.&#160;&#160; Most importantly, the appearance of the content was not affected by the header’s appearance. </p>

<p>Now, in one case, I do want to determine the font appearance of all the children in an Expander’s content property.&#160;&#160; As you can seen in the screen shot, the commands are in a larger, bold font style.&#160; </p>

<p>To accomplish this, I simply created a style derived from the main expander style -like this:</p>

<pre class="code">    <span style="color: blue">&lt;</span><span style="color: #a31515">Style </span><span style="color: red">x</span><span style="color: blue">:</span><span style="color: red">Key</span><span style="color: blue">=&quot;MainViewExpanderCommands&quot; 
           </span><span style="color: red">BasedOn</span><span style="color: blue">=&quot;{</span><span style="color: #a31515">StaticResource </span><span style="color: red">MainViewExpander</span><span style="color: blue">}&quot;  
           </span><span style="color: red">TargetType</span><span style="color: blue">=&quot;Expander&quot;
           &gt;
        &lt;</span><span style="color: #a31515">Setter </span><span style="color: red">Property</span><span style="color: blue">=&quot;FontSize&quot; </span><span style="color: red">Value</span><span style="color: blue">=&quot;20&quot; /&gt;
        &lt;</span><span style="color: #a31515">Setter </span><span style="color: red">Property</span><span style="color: blue">=&quot;FontWeight&quot; </span><span style="color: red">Value</span><span style="color: blue">=&quot;Bold&quot; /&gt;
    &lt;/</span><span style="color: #a31515">Style</span><span style="color: blue">&gt;
</span></pre>

<p><a href="http://11011.net/software/vspaste"></a>&#160;</p>

<p>Then, in the <strong>MainView.xaml</strong> file, I used the derived style like this:</p>

<pre class="code">        <span style="color: blue">&lt;</span><span style="color: #a31515">Expander 
            </span><span style="color: red">Header</span><span style="color: blue">=&quot;Commands&quot; 
            </span><span style="color: red">Grid.Column</span><span style="color: blue">=&quot;0&quot; 
            </span><span style="color: red">IsExpanded</span><span>=&quot;True&quot; 
            <strong><font size="4">Style</font></strong></span><strong><font size="4"><span style="color: blue">=&quot;{</span><span style="color: #a31515">StaticResource <br />                 </span></font></strong><span><strong><font size="5"><font size="4">MainViewExpanderCommands</font>}&quot;</font></strong>
            &gt;
            &lt;</span><span style="color: #a31515">StackPanel</span><span style="color: blue">&gt;
                &lt;</span><span style="color: #a31515">Label </span><span style="color: red">Content</span><span style="color: blue">=&quot;Open&quot;    </span><span style="color: red">Foreground</span><span style="color: blue">=&quot;#FFB4B4A9&quot; /&gt;
                &lt;</span><span style="color: #a31515">Label </span><span style="color: red">Content</span><span style="color: blue">=&quot;Save&quot;    </span><span style="color: red">Foreground</span><span style="color: blue">=&quot;#FFB4B4A9&quot;/&gt;
                &lt;</span><span style="color: #a31515">Label </span><span style="color: red">Content</span><span style="color: blue">=&quot;Save As&quot; </span><span style="color: red">Foreground</span><span style="color: blue">=&quot;#FFB4B4A9&quot;/&gt;
                &lt;</span><span style="color: #a31515">Label </span><span style="color: red">Content</span><span style="color: blue">=&quot;Close&quot;   </span><span style="color: red">Foreground</span><span style="color: blue">=&quot;#FFB4B4A9&quot;/&gt;
            &lt;/</span><span style="color: #a31515">StackPanel</span><span style="color: blue">&gt;
        &lt;/</span><span style="color: #a31515">Expander</span><span style="color: blue">&gt;
</span></pre>

<p><a href="http://11011.net/software/vspaste"></a>&#160;</p>

<p>This worked fine – mostly.&#160; If you look, you will see that each of the labels has the foreground set to a grey color.&#160;&#160; I tried to do this in the derived style, bit alas, this didn’t work because the the intervening stack panel (which is the content for the expander) does not have the foreground property, so it is not inherited. </p>

<p align="center"><a href="http://cid-5424e22be0b9172a.skydrive.live.com/self.aspx/BlogPostAttachments/JobChooser-Setup.exe" target="_blank"><strong><font size="4">Here is the source code download</font></strong></a></p>

<p>This code builds with the <a href="http://msdn.microsoft.com/en-us/vstudio/dd582936.aspx" target="_blank">release candidate version</a> of <a href="http://www.microsoft.com/visualstudio/en-us/pre-order-visual-studio-2010?CR_CC=100340689&amp;WT.mc_id=SEARCH&amp;WT.srch=1&amp;CR_SCC=100340689" target="_blank">Visual Studio 2010</a>.&#160;&#160; It does not need any additional components (like NUnit). </p>

<p>Installing and building the project is easy:&#160;&#160; Just download and run the installer.&#160;&#160; It will put the project on your desktop.&#160; Note, it doesn’t really ‘install’ anything – there are no shortcuts and it doesn’t write to the registry.&#160; You can move the sample directory wherever you would like, or just delete it when you are done.&#160; No un-installing is needed.&#160;&#160; The contents are licensed with the <a href="http://opensource.org/licenses/ms-pl.html">Microsoft Public License</a>.</p>

<p><strong><u>Credit </u></strong>– I’d like to thank <a href="http://joshsmithonwpf.wordpress.com/" target="_blank">Josh Smith</a> for his excellent examples of using the MVVM design pattern.&#160;&#160; All my new WPF projects are MVVM and I learned the ropes from his blog posts.&#160; The MVVM classes in this example are inspired by Josh’s MSDN article <a href="http://msdn.microsoft.com/en-us/magazine/dd419663.aspx" target="_blank"><strong>here</strong></a>.&#160;&#160; I’m still a noob with both WPF and MVVM – the learning curve is very steep, and long.&#160; But Josh’s blog and articles have been hugely helpful (as have <a href="http://delicious.com/foredecker/wpf+blogs" target="_blank">many others</a>…)</p>]]></content:encoded>
    </item>
    <item>
      <title>BizzySpinner 2 – A WPF Spinning Busy State Indicator (with source)</title>
      <link>https://docs.microsoft.com/archive/blogs/pigscanfly/bizzyspinner-2-a-wpf-spinning-busy-state-indicator-with-source</link>
      <pubDate>Sun, 10 Jan 2010 20:00:00 GMT</pubDate>
      <dc:creator><![CDATA[rgr]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/pigscanfly/2010/01/10/bizzyspinner-2-a-wpf-spinning-busy-state-indicator-with-source/</guid>
      <description><![CDATA[I’ve made a key improvement to my BizzySpinner control form my last post.&nbsp; It now starts and...]]></description>
      <content:encoded><![CDATA[<P>I’ve made a key improvement to my BizzySpinner control form my <A href="http://foredecker.wordpress.com/2010/01/01/bizzyspinner-a-wpf-spinning-busy-sate-indicator-with-source/" target=_blank mce_href="http://foredecker.wordpress.com/2010/01/01/bizzyspinner-a-wpf-spinning-busy-sate-indicator-with-source/">last post</A>.&nbsp; It now starts and stop smoothly instead of abruptly.&nbsp; This is quite visually attractive.&nbsp; But it was somewhat non-trivial to do.&nbsp;&nbsp; </P>
<P>In my first example, I had a single simple animation that was either running or stopped.&nbsp; The animation behavior is now like this:</P>
<P><A href="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/BlogFileStorage/blogs_msdn/pigscanfly/WindowsLiveWriter/BizzySpinner2AWPFSpinningBusyStateIndica_D4F8/BizzySpinnerAcceleration_6.png" original-url="http://blogs.msdn.com/blogfiles/pigscanfly/WindowsLiveWriter/BizzySpinner2AWPFSpinningBusyStateIndica_D4F8/BizzySpinnerAcceleration_6.png" mce_href="http://blogs.msdn.com/blogfiles/pigscanfly/WindowsLiveWriter/BizzySpinner2AWPFSpinningBusyStateIndica_D4F8/BizzySpinnerAcceleration_6.png"><IMG style="BORDER-RIGHT-WIDTH: 0px; DISPLAY: block; FLOAT: none; BORDER-TOP-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; MARGIN-LEFT: auto; BORDER-LEFT-WIDTH: 0px; MARGIN-RIGHT: auto" title=BizzySpinnerAcceleration border=0 alt=BizzySpinnerAcceleration src="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/BlogFileStorage/blogs_msdn/pigscanfly/WindowsLiveWriter/BizzySpinner2AWPFSpinningBusyStateIndica_D4F8/BizzySpinnerAcceleration_thumb_2.png" original-url="http://blogs.msdn.com/blogfiles/pigscanfly/WindowsLiveWriter/BizzySpinner2AWPFSpinningBusyStateIndica_D4F8/BizzySpinnerAcceleration_thumb_2.png" width=594 height=260 mce_src="http://blogs.msdn.com/blogfiles/pigscanfly/WindowsLiveWriter/BizzySpinner2AWPFSpinningBusyStateIndica_D4F8/BizzySpinnerAcceleration_thumb_2.png"></A> </P>
<P>I tried to do this all in XAML but it proved quite complex to handle in in that language.&nbsp;&nbsp; This was complicated as there are two key dependency properties to deal with that leads to several states: The <STRONG>Spin</STRONG> property controls the actually spinning state.&nbsp;&nbsp; And the <STRONG>IsEnabled</STRONG> property inherited from <STRONG>UIElement</STRONG>.&nbsp; Both must work correctly together. </P>
<P>This gave me two significant problems:</P>
<OL>
<LI>The XAML was really complicated and difficult to read.&nbsp; I don’t know about you, but to me, XAML is very verbose and difficult to read.&nbsp; Syntax highlighting helps, but only to a degree.&nbsp;&nbsp; There is also no such thing as a XAML debugger so a lot of trial and error is involved with large amounts of XAML.&nbsp;&nbsp; <A href="http://www.kaxaml.com/" target=_blank mce_href="http://www.kaxaml.com/">Kaxaml</A> is really helpful, but this was hard even with that tool. <BR></LI>
<LI>I couldn’t get a fully correct state machine in XAML: No matter what I tried I could toggle the IsEnabled and Spin dependency properties and cause the spinner to “jump” unattractively.&nbsp;&nbsp;&nbsp; <BR></LI></OL>
<P><A href="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/BlogFileStorage/blogs_msdn/pigscanfly/WindowsLiveWriter/BizzySpinner2AWPFSpinningBusyStateIndica_D4F8/BizzySpinnerAcceleration-Page2_2.png" original-url="http://blogs.msdn.com/blogfiles/pigscanfly/WindowsLiveWriter/BizzySpinner2AWPFSpinningBusyStateIndica_D4F8/BizzySpinnerAcceleration-Page2_2.png" mce_href="http://blogs.msdn.com/blogfiles/pigscanfly/WindowsLiveWriter/BizzySpinner2AWPFSpinningBusyStateIndica_D4F8/BizzySpinnerAcceleration-Page2_2.png"><IMG style="BORDER-RIGHT-WIDTH: 0px; DISPLAY: inline; BORDER-TOP-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; MARGIN-LEFT: 0px; BORDER-LEFT-WIDTH: 0px; MARGIN-RIGHT: 0px" title=BizzySpinnerAcceleration-Page2 border=0 alt=BizzySpinnerAcceleration-Page2 align=right src="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/BlogFileStorage/blogs_msdn/pigscanfly/WindowsLiveWriter/BizzySpinner2AWPFSpinningBusyStateIndica_D4F8/BizzySpinnerAcceleration-Page2_thumb.png" original-url="http://blogs.msdn.com/blogfiles/pigscanfly/WindowsLiveWriter/BizzySpinner2AWPFSpinningBusyStateIndica_D4F8/BizzySpinnerAcceleration-Page2_thumb.png" width=248 height=415 mce_src="http://blogs.msdn.com/blogfiles/pigscanfly/WindowsLiveWriter/BizzySpinner2AWPFSpinningBusyStateIndica_D4F8/BizzySpinnerAcceleration-Page2_thumb.png"></A> So, I simply used C# code to do this.&nbsp;&nbsp; This approach was much simpler.&nbsp;&nbsp; It was easy to implement the two cooperating state machines needed to implement all cases.&nbsp;&nbsp; The spinning state machine is shown to the right.&nbsp;&nbsp; It has four states and six transitions – not at all difficult to implement.</P>
<P>This state machine is implemented in the <STRONG>ControlSpinning() </STRONG>function on line 432 in BizzySpinner.xaml.cs.</P>
<P>The transitions caused by the <STRONG>SpinUp</STRONG> and <STRONG>SpinDown</STRONG> values are straight forward and implemented using a couple of switch statements</P>
<P>The transitions labeled <EM>Acceleration Complete </EM>and <EM>Deceleration Complete </EM>are more interesting:&nbsp; they are implemented using the Completed event on the DoubleAnimation using to spin the control.&nbsp; </P>
<P>For example when the spinner goes form the <EM>Not Spinning</EM> state to the <EM>Accelerating </EM>state, the code simply attaches a function to the animation’s Completed event like this:</P>
<DIV style="PADDING-BOTTOM: 0px; MARGIN: 0px; PADDING-LEFT: 0px; PADDING-RIGHT: 0px; DISPLAY: inline; FLOAT: none; PADDING-TOP: 0px" id=scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:621c2844-9dbe-4b78-b321-f4cb15b08483 class=wlWriterEditableSmartContent>
<DIV style="BORDER-BOTTOM: #000080 1px solid; BORDER-LEFT: #000080 1px solid; FONT-FAMILY: 'Courier New', Courier, Monospace; COLOR: #000; FONT-SIZE: 10pt; BORDER-TOP: #000080 1px solid; BORDER-RIGHT: #000080 1px solid">
<DIV style="PADDING-BOTTOM: 2px; PADDING-LEFT: 5px; PADDING-RIGHT: 5px; FONT-FAMILY: Verdana, Tahoma, Arial, sans-serif; BACKGROUND: #000080; COLOR: #fff; FONT-WEIGHT: bold; PADDING-TOP: 2px">Code Snippet</DIV>
<DIV style="BACKGROUND: #ddd; MAX-HEIGHT: 300px; OVERFLOW: auto">
<OL style="PADDING-BOTTOM: 0px; MARGIN: 0px 0px 0px 2.5em; PADDING-LEFT: 5px; PADDING-RIGHT: 0px; BACKGROUND: #ffffff; PADDING-TOP: 0px">
<LI>spinAnimation.From = SpinAngle;</LI>
<LI style="BACKGROUND: #f3f3f3">spinAnimation.To = (SpinAngle + (OneRotation / 8));</LI>
<LI>spinAnimation.Duration = <SPAN style="COLOR: #0000ff">new</SPAN> <SPAN style="COLOR: #2b91af">Duration</SPAN>(<SPAN style="COLOR: #2b91af">TimeSpan</SPAN>.FromSeconds(SpinRate/4));</LI>
<LI style="BACKGROUND: #f3f3f3">spinAnimation.DecelerationRatio = 0.0;</LI>
<LI>spinAnimation.AccelerationRatio = 1.0;</LI>
<LI style="BACKGROUND: #f3f3f3"></LI>
<LI>spinAnimation.Completed += SpinContinuously;</LI>
<LI style="BACKGROUND: #f3f3f3"></LI>
<LI>theSpinState = <SPAN style="COLOR: #2b91af">SpinState</SPAN>.Accelerating;</LI>
<LI style="BACKGROUND: #f3f3f3"></LI>
<LI><SPAN style="COLOR: #0000ff">this</SPAN>.BeginAnimation(SpinAngleProperty, spinAnimation);</LI></OL></DIV></DIV></DIV>
<P>This is the code that causes the spinner to accelerate to its normal spinning rate.&nbsp; The key line is #7.&nbsp;&nbsp; When the spinner has finished accelerating the <STRONG>SpinContinuously</STRONG> member is called.&nbsp; It looks like this:</P>
<P mce_keep="true">&nbsp;</P>
<DIV style="PADDING-BOTTOM: 0px; MARGIN: 0px; PADDING-LEFT: 0px; PADDING-RIGHT: 0px; DISPLAY: inline; FLOAT: none; PADDING-TOP: 0px" id=scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:7d60c14e-6fe8-4e05-94a2-d21432c1ca99 class=wlWriterEditableSmartContent>
<DIV style="BORDER-BOTTOM: #000080 1px solid; BORDER-LEFT: #000080 1px solid; FONT-FAMILY: 'Courier New', Courier, Monospace; COLOR: #000; FONT-SIZE: 10pt; BORDER-TOP: #000080 1px solid; BORDER-RIGHT: #000080 1px solid">
<DIV style="PADDING-BOTTOM: 2px; PADDING-LEFT: 5px; PADDING-RIGHT: 5px; FONT-FAMILY: Verdana, Tahoma, Arial, sans-serif; BACKGROUND: #000080; COLOR: #fff; FONT-WEIGHT: bold; PADDING-TOP: 2px">Code Snippet</DIV>
<DIV style="BACKGROUND: #ddd; MAX-HEIGHT: 300px; OVERFLOW: auto">
<OL style="PADDING-BOTTOM: 0px; MARGIN: 0px 0px 0px 2.5em; PADDING-LEFT: 5px; PADDING-RIGHT: 0px; BACKGROUND: #ffffff; PADDING-TOP: 0px">
<LI><SPAN style="COLOR: #0000ff">void</SPAN> SpinContinuously(<SPAN style="COLOR: #0000ff">object</SPAN> sender, <SPAN style="COLOR: #2b91af">EventArgs</SPAN> e)</LI>
<LI style="BACKGROUND: #f3f3f3">{</LI>
<LI>&nbsp;&nbsp;&nbsp;&nbsp;spinAnimation.Completed -= SpinContinuously;</LI>
<LI style="BACKGROUND: #f3f3f3"></LI>
<LI>&nbsp;&nbsp;&nbsp;&nbsp;spinAnimation.From = SpinAngle;</LI>
<LI style="BACKGROUND: #f3f3f3">&nbsp;&nbsp;&nbsp;&nbsp;spinAnimation.To = SpinAngle + OneRotation;</LI>
<LI>&nbsp;&nbsp;&nbsp;&nbsp;spinAnimation.Duration = <SPAN style="COLOR: #0000ff">new</SPAN> <SPAN style="COLOR: #2b91af">Duration</SPAN>(<SPAN style="COLOR: #2b91af">TimeSpan</SPAN>.FromSeconds(SpinRate));</LI>
<LI style="BACKGROUND: #f3f3f3">&nbsp;&nbsp;&nbsp;&nbsp;spinAnimation.DecelerationRatio = 0.0;</LI>
<LI>&nbsp;&nbsp;&nbsp;&nbsp;spinAnimation.AccelerationRatio = 0.0;</LI>
<LI style="BACKGROUND: #f3f3f3">&nbsp;&nbsp;&nbsp;&nbsp;spinAnimation.RepeatBehavior = <SPAN style="COLOR: #2b91af">RepeatBehavior</SPAN>.Forever;</LI>
<LI></LI>
<LI style="BACKGROUND: #f3f3f3">&nbsp;&nbsp;&nbsp;&nbsp;theSpinState = <SPAN style="COLOR: #2b91af">SpinState</SPAN>.Running;</LI>
<LI></LI>
<LI style="BACKGROUND: #f3f3f3">&nbsp;&nbsp;&nbsp;&nbsp;<SPAN style="COLOR: #0000ff">this</SPAN>.BeginAnimation(SpinAngleProperty, spinAnimation);</LI>
<LI>}</LI></OL></DIV></DIV></DIV>
<P mce_keep="true">&nbsp;</P>
<P>Note line 3 which disconnects the <STRONG>SpinContinuously</STRONG>&nbsp; from the animations Completed event.&nbsp;&nbsp; This is super important as we don’t want this called again because the next state transition when the animation completes is a different one.</P>
<P>The other important state machine is the one that handles the <STRONG>IsEnabled</STRONG> and Spin dependency properties.&nbsp;&nbsp; This is what sends the <STRONG>SpinUp</STRONG> and <STRONG>SpinDown</STRONG> commands to the spinning state machine.</P>
<P><A href="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/BlogFileStorage/blogs_msdn/pigscanfly/WindowsLiveWriter/BizzySpinner2AWPFSpinningBusyStateIndica_D4F8/BizzySpinnerAcceleration-Page3_2.png" original-url="http://blogs.msdn.com/blogfiles/pigscanfly/WindowsLiveWriter/BizzySpinner2AWPFSpinningBusyStateIndica_D4F8/BizzySpinnerAcceleration-Page3_2.png" mce_href="http://blogs.msdn.com/blogfiles/pigscanfly/WindowsLiveWriter/BizzySpinner2AWPFSpinningBusyStateIndica_D4F8/BizzySpinnerAcceleration-Page3_2.png"><IMG style="BORDER-RIGHT-WIDTH: 0px; DISPLAY: block; FLOAT: none; BORDER-TOP-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; MARGIN-LEFT: auto; BORDER-LEFT-WIDTH: 0px; MARGIN-RIGHT: auto" title=BizzySpinnerAcceleration-Page3 border=0 alt=BizzySpinnerAcceleration-Page3 src="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/BlogFileStorage/blogs_msdn/pigscanfly/WindowsLiveWriter/BizzySpinner2AWPFSpinningBusyStateIndica_D4F8/BizzySpinnerAcceleration-Page3_thumb.png" original-url="http://blogs.msdn.com/blogfiles/pigscanfly/WindowsLiveWriter/BizzySpinner2AWPFSpinningBusyStateIndica_D4F8/BizzySpinnerAcceleration-Page3_thumb.png" width=563 height=424 mce_src="http://blogs.msdn.com/blogfiles/pigscanfly/WindowsLiveWriter/BizzySpinner2AWPFSpinningBusyStateIndica_D4F8/BizzySpinnerAcceleration-Page3_thumb.png"></A> </P>
<P>This is simpler than it looks:&nbsp; there are only four important transitions – the ones in green where the <STRONG>SpinUp</STRONG> and <STRONG>SpinDown</STRONG> commands are sent to the spinning state machine. </P>
<P>This is all handled easily in the <STRONG>IsEnabledChanged</STRONG> event handler like this:</P>
<P mce_keep="true">&nbsp;</P>
<DIV style="PADDING-BOTTOM: 0px; MARGIN: 0px; PADDING-LEFT: 0px; PADDING-RIGHT: 0px; DISPLAY: inline; FLOAT: none; PADDING-TOP: 0px" id=scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:96d2df56-66fa-4c4a-83b8-f49162d36d05 class=wlWriterEditableSmartContent>
<DIV style="BORDER-BOTTOM: #000080 1px solid; BORDER-LEFT: #000080 1px solid; FONT-FAMILY: 'Courier New', Courier, Monospace; COLOR: #000; FONT-SIZE: 10pt; BORDER-TOP: #000080 1px solid; BORDER-RIGHT: #000080 1px solid">
<DIV style="PADDING-BOTTOM: 2px; PADDING-LEFT: 5px; PADDING-RIGHT: 5px; FONT-FAMILY: Verdana, Tahoma, Arial, sans-serif; BACKGROUND: #000080; COLOR: #fff; FONT-WEIGHT: bold; PADDING-TOP: 2px">Code Snippet</DIV>
<DIV style="BACKGROUND: #ddd; MAX-HEIGHT: 300px; OVERFLOW: auto">
<OL style="PADDING-BOTTOM: 0px; MARGIN: 0px 0px 0px 2.5em; PADDING-LEFT: 5px; PADDING-RIGHT: 0px; BACKGROUND: #ffffff; PADDING-TOP: 0px">
<LI><SPAN style="COLOR: #0000ff">private</SPAN> <SPAN style="COLOR: #0000ff">void</SPAN> IsEnabledChangedHandler(<SPAN style="COLOR: #2b91af">Object</SPAN> sender, <SPAN style="COLOR: #2b91af">DependencyPropertyChangedEventArgs</SPAN> e)</LI>
<LI style="BACKGROUND: #f3f3f3">{</LI>
<LI>&nbsp;&nbsp;&nbsp;&nbsp;<SPAN style="COLOR: #0000ff">if</SPAN> ( !(<SPAN style="COLOR: #0000ff">bool</SPAN>)e.NewValue)</LI>
<LI style="BACKGROUND: #f3f3f3">&nbsp;&nbsp;&nbsp;&nbsp;{</LI>
<LI>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<SPAN style="COLOR: #008000">//</SPAN></LI>
<LI style="BACKGROUND: #f3f3f3">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<SPAN style="COLOR: #008000">// Going enabled</SPAN></LI>
<LI>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<SPAN style="COLOR: #008000">//</SPAN></LI>
<LI style="BACKGROUND: #f3f3f3">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Background = BackgroundBrushSave;</LI>
<LI>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;LeaderBrush = LeaderBrushSave;</LI>
<LI style="BACKGROUND: #f3f3f3">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;TailBrush = TailBrushSave;</LI>
<LI></LI>
<LI style="BACKGROUND: #f3f3f3">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<SPAN style="COLOR: #008000">// The control is enabled, turn on spinning if the Spin property is ture</SPAN></LI>
<LI>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ControlSpinning(Spin ? <SPAN style="COLOR: #2b91af">SpinCommand</SPAN>.SpinUp : <SPAN style="COLOR: #2b91af">SpinCommand</SPAN>.SpinDown);</LI>
<LI style="BACKGROUND: #f3f3f3">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</LI>
<LI>&nbsp;&nbsp;&nbsp;&nbsp;} <SPAN style="COLOR: #0000ff">else</SPAN> {</LI>
<LI style="BACKGROUND: #f3f3f3">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<SPAN style="COLOR: #008000">//</SPAN></LI>
<LI>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<SPAN style="COLOR: #008000">// Going disabled</SPAN></LI>
<LI style="BACKGROUND: #f3f3f3">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<SPAN style="COLOR: #008000">//</SPAN></LI>
<LI>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<SPAN style="COLOR: #0000ff">if</SPAN> (theSpinState == <SPAN style="COLOR: #2b91af">SpinState</SPAN>.NotSpinning)</LI>
<LI style="BACKGROUND: #f3f3f3">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{</LI>
<LI>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SetDisabledBrushes();</LI>
<LI style="BACKGROUND: #f3f3f3">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</LI>
<LI>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<SPAN style="COLOR: #0000ff">else</SPAN></LI>
<LI style="BACKGROUND: #f3f3f3">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{</LI>
<LI>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ControlSpinning(<SPAN style="COLOR: #2b91af">SpinCommand</SPAN>.SpinDown);</LI>
<LI style="BACKGROUND: #f3f3f3">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</LI>
<LI>&nbsp;&nbsp;&nbsp;&nbsp;}</LI>
<LI style="BACKGROUND: #f3f3f3">}</LI></OL></DIV></DIV></DIV>
<P mce_keep="true">&nbsp;</P>
<P>The resulting animation is very pleasing – the control spins up and down smoothly.&nbsp;&nbsp; Its rotational rate can also be controlled dynamically.</P>
<P>You will need <A href="http://nunit.com/" target=_blank mce_href="http://nunit.com">NUnit</A> 2.5.3 (<A href="http://nunit.com/index.php?p=download" target=_blank mce_href="http://nunit.com/index.php?p=download">download</A>) as I’ve added assertions. The code builds for C# 3.0 and .NET 3.5 using the client profile.&nbsp; As with the last post, the project is for the <A href="http://www.microsoft.com/visualstudio/en-us/products/2010/default.mspx?CR_CC=100253207&amp;WT.mc_id=SEARCH&amp;WT.srch=1&amp;CR_SCC=100253207" target=_blank mce_href="http://www.microsoft.com/visualstudio/en-us/products/2010/default.mspx?CR_CC=100253207&amp;WT.mc_id=SEARCH&amp;WT.srch=1&amp;CR_SCC=100253207">Visual Studio 2010 BETA</A> which you can download for free.. </P>
<P>Installing and building the project is easy:&nbsp;&nbsp; Just download and run the installer.&nbsp;&nbsp; It will put the project on your desktop.&nbsp; Note, it doesn’t really ‘install’ anything – there are no shortcuts and it doesn’t write to the registry.&nbsp; You can move the sample directory wherever you would like, or just delete it when you are done.&nbsp; No un-installing is needed.&nbsp;&nbsp; Also note that the contents are licensed with the <A href="http://opensource.org/licenses/ms-pl.html" mce_href="http://opensource.org/licenses/ms-pl.html">Microsoft Public License</A>.</P>
<P><STRONG><A href="http://cid-5424e22be0b9172a.skydrive.live.com/self.aspx/BlogPostAttachments/BizzySpinnerExample-2-Setup.exe" target=_blank mce_href="http://cid-5424e22be0b9172a.skydrive.live.com/self.aspx/BlogPostAttachments/BizzySpinnerExample-2-Setup.exe">Here is the source code download</A></STRONG></P>]]></content:encoded>
    </item>
    <item>
      <title>BizzySpinner – A WPF Spinning Busy Sate Indicator (with source)</title>
      <link>https://docs.microsoft.com/archive/blogs/pigscanfly/bizzyspinner-a-wpf-spinning-busy-sate-indicator-with-source</link>
      <pubDate>Thu, 31 Dec 2009 19:13:00 GMT</pubDate>
      <dc:creator><![CDATA[rgr]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/pigscanfly/2009/12/31/bizzyspinner-a-wpf-spinning-busy-sate-indicator-with-source/</guid>
      <description><![CDATA[I’ve been working on a pet project that does a lot of network I/O and database queries.&nbsp;&nbsp;...]]></description>
      <content:encoded><![CDATA[<P align=left>I’ve been working on a pet project that does a lot of network I/O and database queries.&nbsp;&nbsp; One of the things I need to do is run long running things in the background – off the UI thread and keep the UI responsive.&nbsp; So, I’ve built a spinning busy state indicator.&nbsp; I’ve included the source code as well.</P>
<P align=left><A href="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/BlogFileStorage/blogs_msdn/pigscanfly/WindowsLiveWriter/BizzySpinnerAWPFBusySateIndicator_EF9A/BizzySpinner_2.png" original-url="http://blogs.msdn.com/blogfiles/pigscanfly/WindowsLiveWriter/BizzySpinnerAWPFBusySateIndicator_EF9A/BizzySpinner_2.png" mce_href="http://blogs.msdn.com/blogfiles/pigscanfly/WindowsLiveWriter/BizzySpinnerAWPFBusySateIndicator_EF9A/BizzySpinner_2.png"><IMG style="BORDER-RIGHT-WIDTH: 0px; DISPLAY: inline; BORDER-TOP-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; MARGIN-LEFT: 0px; BORDER-LEFT-WIDTH: 0px; MARGIN-RIGHT: 0px" title=BizzySpinner border=0 alt=BizzySpinner align=right src="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/BlogFileStorage/blogs_msdn/pigscanfly/WindowsLiveWriter/BizzySpinnerAWPFBusySateIndicator_EF9A/BizzySpinner_thumb.png" original-url="http://blogs.msdn.com/blogfiles/pigscanfly/WindowsLiveWriter/BizzySpinnerAWPFBusySateIndicator_EF9A/BizzySpinner_thumb.png" width=86 height=80 mce_src="http://blogs.msdn.com/blogfiles/pigscanfly/WindowsLiveWriter/BizzySpinnerAWPFBusySateIndicator_EF9A/BizzySpinner_thumb.png"></A>My graphical design skills are pretty lame, but I saw some others on the net and Mine doesn’t look too bad.&nbsp; </P>
<P>I’m still learning WPF.&nbsp; I started about two years ago (see my <A href="http://blogs.msdn.com/pigscanfly/archive/tags/WPF/default.aspx" target=_blank mce_href="http://blogs.msdn.com/pigscanfly/archive/tags/WPF/default.aspx">old posts</A>) but was distracted by shipping a little thing we call Windows-7.&nbsp; Given our team is very likely to build some production WPF based products, I need to get back on the stick and learn the WPF basics.</P>
<P align=left>As with any new project, I found several good examples on the ‘tubes.&nbsp; <A href="http://www.codeproject.com/Members/Sacha-Barber" target=_blank mce_href="http://www.codeproject.com/Members/Sacha-Barber">Sacha Barber’s</A> <A href="http://www.codeproject.com/Articles/35288/WPF-Circular-Progress-Bar.aspx" target=_blank mce_href="http://www.codeproject.com/Articles/35288/WPF-Circular-Progress-Bar.aspx">example</A> on <A href="http://www.codeproject.com/" target=_blank mce_href="http://www.codeproject.com">CodeProject.com</A>&nbsp; was a good start and where I got the inspiration for my basic graphical design.&nbsp;&nbsp; <A href="http://www.codeproject.com/KB/progress/ProgressIndicator.aspx" target=_blank mce_href="http://www.codeproject.com/KB/progress/ProgressIndicator.aspx">This one</A> is similar, and <A href="http://www.codeproject.com/KB/progress/AsyncProgressControl.aspx" target=_blank mce_href="http://www.codeproject.com/KB/progress/AsyncProgressControl.aspx">this one</A> is native on GDI+.&nbsp; Here is <A href="http://gallery.expression.microsoft.com/en-us/BusyIndicator" target=_blank mce_href="http://gallery.expression.microsoft.com/en-us/BusyIndicator">another one</A> on the <A href="http://gallery.expression.microsoft.com/en-us/site/search?f[0].Type=RootCategory&amp;f[0].Value=behaviors" target=_blank mce_href="http://gallery.expression.microsoft.com/en-us/site/search?f[0].Type=RootCategory&amp;f[0].Value=behaviors">Expression Behaviors Gallery</A>.</P>
<P align=left>While all are good examples, I wanted to code my own completely from scratch.&nbsp;&nbsp; I had a few goals in mind:</P>
<OL>
<LI>
<DIV align=left>Full support for styles and templates</DIV></LI>
<LI>
<DIV align=left>Fully sizeable </DIV></LI>
<LI>
<DIV align=left>Rotate in either direction</DIV></LI>
<LI>
<DIV align=left>Could be disabled – like most other controls</DIV></LI>
<LI>
<DIV align=left>Could be ‘spun’ manually –without an animation</DIV></LI></OL>
<P align=left>This means I need to build a fully custom WPF control – a class that derives from <A href="http://msdn.microsoft.com/en-us/library/system.windows.controls.control.aspx" target=_blank mce_href="http://msdn.microsoft.com/en-us/library/system.windows.controls.control.aspx">System.Windows.Controls.Control.</A>&nbsp; This turned out to be really easy – once I got past the learning curve!</P>
<P align=left>Until recently, my WPF code and XAML were pretty klunky – the code seemed complicated to me and had a faint ‘just not right’ <A href="http://en.wikipedia.org/wiki/Code_smell" target=_blank mce_href="http://en.wikipedia.org/wiki/Code_smell">code smell</A>.&nbsp; The more I looked at it, the riper it got.&nbsp;&nbsp; You can see some of this stinky cheese <A href="http://blogs.msdn.com/pigscanfly/archive/tags/WPF/default.aspx" target=_blank mce_href="http://blogs.msdn.com/pigscanfly/archive/tags/WPF/default.aspx">here</A>.&nbsp;&nbsp; [ wow?&nbsp; was that really two years ago?&nbsp; I suppose that’s why they call shipping Windows-7 ‘work’ ]</P>
<P align=left>In any case, I’ve had the time to do some hacking recently and I’ve learned a ton.&nbsp;&nbsp; One thing I’ve noted is there is a <EM>LOT </EM>more WPF information on the ‘tubes than there was two years ago, and the <A href="http://msdn.microsoft.com/en-us/library/ms754130.aspx" target=_blank mce_href="http://msdn.microsoft.com/en-us/library/ms754130.aspx">WPF MSDN Library documentation</A> is way, way better.&nbsp;&nbsp; This made my recent efforts much easier.</P>
<P align=left>The major thing I learned recently is that I had been going about WPF develop all <EM>wrong</EM>.&nbsp; All my previous hacks had been procedural in nature – doing the UI work in code.&nbsp;&nbsp; I hadn’t really groked how fundamental <A href="http://msdn.microsoft.com/en-us/library/ms752914.aspx" target=_blank mce_href="http://msdn.microsoft.com/en-us/library/ms752914.aspx">dependency properties</A> and <A href="http://msdn.microsoft.com/en-us/library/ms752347.aspx" target=_blank mce_href="http://msdn.microsoft.com/en-us/library/ms752347.aspx">data binding</A> are to WPF development.&nbsp; These simply are not framework features you can use – they are fundamental constructs.&nbsp; Tying things together with dependency properties and data bindings is just <EM>they way</EM> to do things in WPF.&nbsp;&nbsp; It took me a bit to grok it, but I had one of those ah-Ha! moments are few days ago.&nbsp; Groovy. </P>
<P align=left>As with my other posts, I’m including the fully buildable source code.&nbsp; The code currently uses the .NET 3.5 <A href="http://msdn.microsoft.com/en-us/library/cc656912.aspx" target=_blank mce_href="http://msdn.microsoft.com/en-us/library/cc656912.aspx">Client Profile</A> but it builds with <A href="http://www.microsoft.com/visualstudio/en-us/products/2010/default.mspx?CR_CC=100253207&amp;WT.mc_id=SEARCH&amp;WT.srch=1&amp;CR_SCC=100253207" target=_blank mce_href="http://www.microsoft.com/visualstudio/en-us/products/2010/default.mspx?CR_CC=100253207&amp;WT.mc_id=SEARCH&amp;WT.srch=1&amp;CR_SCC=100253207">Beta-2 of Visual Studio 2010</A>.&nbsp;&nbsp;&nbsp;&nbsp; You can find the code attached. </P>
<P>The current code is fully functional. I’ve packaged the spinner its own assembly called Fenestra which Latin for ‘window’, clever huh?&nbsp; I’ve also included a developer framework (DF) that lets me test the control.&nbsp; It looks like this:</P>
<P>The DF lets me control the properties including the size, the spin rate and watch the events happen.&nbsp;&nbsp; Its very simple code.&nbsp; In the image above you can see two spinners, the one on the left is the default theme for the control.&nbsp; The one on the right is a templated and styled version.&nbsp;&nbsp;&nbsp; <A href="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/BlogFileStorage/blogs_msdn/pigscanfly/WindowsLiveWriter/BizzySpinnerAWPFBusySateIndicator_EF9A/BizzySpinnerDF_2.png" original-url="http://blogs.msdn.com/blogfiles/pigscanfly/WindowsLiveWriter/BizzySpinnerAWPFBusySateIndicator_EF9A/BizzySpinnerDF_2.png" mce_href="http://blogs.msdn.com/blogfiles/pigscanfly/WindowsLiveWriter/BizzySpinnerAWPFBusySateIndicator_EF9A/BizzySpinnerDF_2.png"><IMG style="BORDER-RIGHT-WIDTH: 0px; DISPLAY: block; FLOAT: none; BORDER-TOP-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; MARGIN-LEFT: auto; BORDER-LEFT-WIDTH: 0px; MARGIN-RIGHT: auto" title=BizzySpinnerDF border=0 alt=BizzySpinnerDF src="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/BlogFileStorage/blogs_msdn/pigscanfly/WindowsLiveWriter/BizzySpinnerAWPFBusySateIndicator_EF9A/BizzySpinnerDF_thumb.png" original-url="http://blogs.msdn.com/blogfiles/pigscanfly/WindowsLiveWriter/BizzySpinnerAWPFBusySateIndicator_EF9A/BizzySpinnerDF_thumb.png" width=244 height=199 mce_src="http://blogs.msdn.com/blogfiles/pigscanfly/WindowsLiveWriter/BizzySpinnerAWPFBusySateIndicator_EF9A/BizzySpinnerDF_thumb.png"></A> </P>
<P>All of the elements are fully style-able.&nbsp;&nbsp; Each item in the spinner is a WPF <A href="http://msdn.microsoft.com/en-us/library/system.windows.shapes.shape(VS.85).aspx" target=_blank mce_href="http://msdn.microsoft.com/en-us/library/system.windows.shapes.shape(VS.85).aspx">Shape</A> which means their key attributes can be bound to the control’s dependency properties.</P>
<P><A href="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/BlogFileStorage/blogs_msdn/pigscanfly/WindowsLiveWriter/BizzySpinnerAWPFBusySateIndicator_EF9A/Circles_2.png" original-url="http://blogs.msdn.com/blogfiles/pigscanfly/WindowsLiveWriter/BizzySpinnerAWPFBusySateIndicator_EF9A/Circles_2.png" mce_href="http://blogs.msdn.com/blogfiles/pigscanfly/WindowsLiveWriter/BizzySpinnerAWPFBusySateIndicator_EF9A/Circles_2.png"><IMG style="BORDER-RIGHT-WIDTH: 0px; DISPLAY: inline; BORDER-TOP-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; MARGIN-LEFT: 0px; BORDER-LEFT-WIDTH: 0px; MARGIN-RIGHT: 0px" title=Circles border=0 alt=Circles align=right src="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/BlogFileStorage/blogs_msdn/pigscanfly/WindowsLiveWriter/BizzySpinnerAWPFBusySateIndicator_EF9A/Circles_thumb.png" original-url="http://blogs.msdn.com/blogfiles/pigscanfly/WindowsLiveWriter/BizzySpinnerAWPFBusySateIndicator_EF9A/Circles_thumb.png" width=97 height=97 mce_src="http://blogs.msdn.com/blogfiles/pigscanfly/WindowsLiveWriter/BizzySpinnerAWPFBusySateIndicator_EF9A/Circles_thumb.png"></A>I drew the fundamental shapes in <A href="http://www.microsoft.com/expression/products/Design_Overview.aspx" target=_blank mce_href="http://www.microsoft.com/expression/products/Design_Overview.aspx">Expression Design 3</A> which has a learning curve all its own.&nbsp; I used it because it directly produces XAML.&nbsp;&nbsp; Once I got the basic knack of using the tool, it wasn’t too hard to do.&nbsp; You can find the original design files in the <STRONG>BizzySpinnerDF</STRONG>&nbsp; directory.&nbsp; They are named Circles.design and Rectangles.design.&nbsp; </P>
<P>Installing and building the project is easy:&nbsp;&nbsp; Just download and run the installer.&nbsp;&nbsp; It will put the project on your desktop.&nbsp; Note, it doesn’t really ‘install’ anything – there are no shortcuts and it doesn’t write to the registry.&nbsp; You can move the sample directory wherever you would like, or just delete it when you are done.&nbsp; No un-installing is needed.&nbsp;&nbsp; Also note that the contents are licensed with the <A href="http://opensource.org/licenses/ms-pl.html" target=_blank mce_href="http://opensource.org/licenses/ms-pl.html">Microsoft Public License</A>. </P>
<H3 align=center><STRONG><FONT color=#ff8000><A href="http://cid-5424e22be0b9172a.skydrive.live.com/browse.aspx/BlogPostAttachments" target=_blank mce_href="http://cid-5424e22be0b9172a.skydrive.live.com/browse.aspx/BlogPostAttachments">Here is the download</A></FONT></STRONG></H3>]]></content:encoded>
    </item>
    <item>
      <title>Stack Walking in Xperf</title>
      <link>https://docs.microsoft.com/archive/blogs/pigscanfly/stack-walking-in-xperf</link>
      <pubDate>Thu, 06 Aug 2009 13:52:25 GMT</pubDate>
      <dc:creator><![CDATA[rgr]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/pigscanfly/2009/08/06/stack-walking-in-xperf/</guid>
      <description><![CDATA[Bruce Dawson is a performance analyst on the client performance team.&#160; He has written this...]]></description>
      <content:encoded><![CDATA[<p><strong></strong></p>  <p>Bruce Dawson is a performance analyst on the client performance team.&#160; He has written this guest post on enabling stack walking using xperf for both 32-bit and 64-bit Windows systems (Vista and Win7).&#160; For more posts on xperf see <a href="http://blogs.msdn.com/pigscanfly/pages/xperf-articles.aspx" target="_blank">this page</a>.</p> <strong></strong>  <h1><strong>Introduction</strong></h1>  <p>When I first started working with xperf I was confused by the many gotchas and settings surrounding the recording of call stacks. It seemed like there were many bits of crucial information needed in order to successfully record call stacks, and these bits were never gathered in one place. In order to save future generations from this complexity (and to give me a convenient reference to look at) I decided to write up what I have learned, while the lessons are still fresh in my memory. </p>  <p><strong><font color="#ff0000">Warning: </font></strong>The syntax examples below make use of ‘-‘ characters and the single quote character. Both of these characters are often altered by word processing software to visually similar but actually different characters, which can lead to obscure syntax errors. If the example syntax doesn’t work then try typing in the command manually instead of using copy/paste to eliminate that as a factor. </p>  <h1><strong>Recording Stack Walks</strong></h1>  <p>In order to enable call stacks in xperf you need to choose what type of event you want call stacks for, make sure that event is being recorded, and then enable call stacks for that type of event. The sampling profile events from the kernel provider (interrupting the CPU every millisecond and recording what it is doing) are one of the main uses of call stacks. The profile events can be enabled with the “PROFILE” kernel flag, or by using some of the kernel groups such as “Base” or “Latency” which include the PROFILE flag. For a list of all the kernel flags and kernel groups use: </p>  <blockquote>   <p><font face="Courier New">xperf -providers k</font></p> </blockquote>  <p>In addition to enabling the sampling profiler we need to enable stack walking on that event with the -stackwalk command. We also need to make sure that the PROC_THREAD and LOADER kernel flags are enabled – so that the xperf tools can identify what modules the code addresses are in. </p>  <p>Putting this together, the following example command will tell xperf to record a trace with sampling profiler call stacks and save it to mytrace.etl: </p>  <blockquote>   <table border="0" cellspacing="0" cellpadding="2" width="400"><tbody>       <tr>         <td valign="top" width="400"><font face="Courier New">xperf -on PROC_THREAD+LOADER+PROFILE -stackwalk profile</font></td>       </tr>        <tr>         <td valign="top" width="400"><font face="Courier New">rem Your scenario goes here…</font></td>       </tr>        <tr>         <td valign="top" width="400"><font face="Courier New">xperf -d mytrace.etl</font></td>       </tr>     </tbody></table> </blockquote>  <p align="left">Alternately, the following command will also work, because the “Latency” kernel group includes all of the necessary kernel flags.</p>  <blockquote>   <table border="0" cellspacing="0" cellpadding="2" width="400"><tbody>       <tr>         <td valign="top" width="400"><font face="Courier New">xperf -on Latency -stackwalk profile</font></td>       </tr>        <tr>         <td valign="top" width="400"><font face="Courier New">rem Your scenario goes here...</font></td>       </tr>        <tr>         <td valign="top" width="400"><font face="Courier New">xperf -d mytrace.etl</font></td>       </tr>     </tbody></table> </blockquote>  <p>Many events can have stack walking enabled using this basic method, so that if you want call stacks for context switches, registry operations, etc., you can get them. You can see the list of events that can have call stacks enabled for them with: </p>  <blockquote>   <p><font face="Courier New">xperf -help stackwalk</font></p> </blockquote>  <p>You can also record call stacks for manifest-based ETW (Event Tracing for Windows) events, but the syntax is quite different, and it only works on Windows 7 and above. When you specify your ETW provider to xperf after “-on” you can specify extra parameters after the provider name, separated by colons. These are flags, a level, and, for manifest-based providers, a list of extra data to record, which can include call stacks. You can leave the flags and level fields blank and just specify ‘stack’ (in single quotes) after three colons like this: </p>  <blockquote>   <table border="0" cellspacing="0" cellpadding="2" width="495"><tbody>       <tr>         <td valign="top" width="493"><font face="Courier New">xperf -on Latency -stackwalk profile -start browse -on Microsoft-IE:::'stack'</font></td>       </tr>        <tr>         <td valign="top" width="493"><font face="Courier New">rem Your scenario goes here...</font></td>       </tr>        <tr>         <td valign="top" width="493"><font face="Courier New">xperf -stop browse -stop -d mytrace.etl</font></td>       </tr>     </tbody></table> </blockquote>  <p>The syntax above starts the kernel session with the “Latency” set of kernel flags, enables stack walking on the profile events, starts a user session called “browse”, and enables the “Microsoft-IE” ETW provider for that session, with call stacks recorded for all of those events. Then, when your scenario is finished it stops the user session, stops the kernel session, and merges the kernel and user traces into “mytrace.etl”. It’s a bit of a mouthful, but it works. </p>  <h3><strong>Operating System Support for XPerf Stack Walks</strong></h3>  <p>Recording stack walks from xperf is not supported in all variations of Windows and does have some prerequisites. Note also that stack walking for classic ETW events is not supported. Owners of classic ETW providers must upgrade their providers to manifest-based to take advantage of stack walking on their custom events.</p>  <p>The following chart summarizes the situation for stack walking on kernel and manifest-based events:</p>  <table border="2" cellspacing="0" cellpadding="2" width="400"><tbody>     <tr>       <td valign="top" width="133">&#160;</td>        <td valign="top" width="133">         <p align="center"><strong>32-bit</strong></p>       </td>        <td valign="top" width="133">         <p align="center"><strong>64-bit</strong></p>       </td>     </tr>      <tr>       <td valign="top" width="133"><strong>XP and below</strong></td>        <td valign="top" width="133">         <p align="center">No</p>       </td>        <td valign="top" width="133">         <p align="center">No</p>       </td>     </tr>      <tr>       <td valign="top" width="133"><strong>Vista RTM*</strong></td>        <td valign="top" width="133">         <p align="center">Yes</p>       </td>        <td valign="top" width="133">         <p align="center">No</p>       </td>     </tr>      <tr>       <td valign="top" width="133"><strong>Vista SP1*</strong></td>        <td valign="top" width="133">         <p align="center">Yes</p>       </td>        <td valign="top" width="133">         <p align="center">Yes**</p>       </td>     </tr>      <tr>       <td valign="top" width="133"><strong>Windows 7</strong></td>        <td valign="top" width="133">         <p align="center">Yes</p>       </td>        <td valign="top" width="133">         <p align="center">Yes**</p>       </td>     </tr>   </tbody></table>  <p>&#160;</p>  <p>* Stack walking not supported for manifest-based ETW events.</p>  <p>** Stack walking on 64-bit requires that the DisablePagingExecutive registry key be set. </p>  <h3><strong>Disable Paging Executive</strong></h3>  <p>In order for tracing to work on 64-bit Windows you need to set the DisablePagingExecutive registry key. This tells the operating system not to page kernel mode drivers and system code to disk, which is a prerequisite for getting 64-bit call stacks using xperf, because 64-bit stack walking depends on metadata in the executable images, and in some situations the xperf stack walk code is not allowed to touch paged out pages. Running the following command from an elevated command prompt will set this registry key for you. </p>  <blockquote>   <p>REG ADD &quot;HKLM\System\CurrentControlSet\Control\Session Manager\Memory Management&quot; -v DisablePagingExecutive -d 0x1 -t REG_DWORD -f </p> </blockquote>  <p>After setting this registry key you will need to reboot your system before you can record call stacks. Having this flag set means that the Windows kernel locks more pages into RAM, so this will probably consume about 10 MB of additional physical memory. </p>  <h1><strong>Looking at Stack Walks</strong></h1>  <p>The call stacks that result from the stack walks are visible in xperfview. You can run xperfview and load your trace or you can invoke it from the command line with: </p>  <blockquote>   <p><font face="Courier New">xperf mytrace.etl</font> </p> </blockquote>  <p>If you enabled the PROFILE kernel flag then you should see one or more CPU Sampling graphs – if they aren’t enabled then use the selector on the left sidebar, or the Graphs menu, to enable one of them. </p>  <p><a href="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/BlogFileStorage/blogs_msdn/pigscanfly/WindowsLiveWriter/StackWalkinginXperf_12FF9/image_2.png" original-url="http://blogs.msdn.com/blogfiles/pigscanfly/WindowsLiveWriter/StackWalkinginXperf_12FF9/image_2.png"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/BlogFileStorage/blogs_msdn/pigscanfly/WindowsLiveWriter/StackWalkinginXperf_12FF9/image_thumb.png" original-url="http://blogs.msdn.com/blogfiles/pigscanfly/WindowsLiveWriter/StackWalkinginXperf_12FF9/image_thumb.png" width="540" height="247" /></a> </p>  <p>From one of the CPU sampling graphs you can select an area of interest and then right-click and select Summary Table. Use the selector on the left sidebar of the summary table, or the Columns menu, to make sure that the Stack column is enabled and visible – this is where your call stacks will be shown. Xperfview summarizes multiple stack walks together, collapsing them down where they are identical. The Count field shows how many stacks were collapsed together on each row (how many times that partial call stack was hit), the Weight column shows an estimate of how many milliseconds of CPU time were spent in that call stack, and the %Weight column shows that as a percentage of total CPU time available.</p>  <p><a href="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/BlogFileStorage/blogs_msdn/pigscanfly/WindowsLiveWriter/StackWalkinginXperf_12FF9/image_4.png" original-url="http://blogs.msdn.com/blogfiles/pigscanfly/WindowsLiveWriter/StackWalkinginXperf_12FF9/image_4.png"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/BlogFileStorage/blogs_msdn/pigscanfly/WindowsLiveWriter/StackWalkinginXperf_12FF9/image_thumb_1.png" original-url="http://blogs.msdn.com/blogfiles/pigscanfly/WindowsLiveWriter/StackWalkinginXperf_12FF9/image_thumb_1.png" width="546" height="250" /></a> </p>  <h3><strong>Sampling Implies Estimation</strong></h3>  <p>CPU sampling is a statistical profiling process. If the number of samples is small, or if the code execution is correlated with the sampling interval, then the results can be off by a large amount. It is important to be aware of the limits of sampling in order to avoid reading too much meaning into a small number of counts.</p>  <h3><strong>Symbols</strong></h3>  <p>If you haven’t loaded symbols then your call stacks will show DLL names followed by question marks, as shown below. You can tell that you’ve recorded a call stack, but the details of what code was executing are still hidden.</p>  <table border="0" cellspacing="0" cellpadding="0"><tbody>     <tr>       <td width="165">Stack</td>        <td width="90">Count</td>        <td width="93">Weight</td>        <td width="141">% Weight</td>     </tr>      <tr>       <td width="165">[Root]</td>        <td width="90">4973</td>        <td width="93">4972.513</td>        <td width="141">93.51</td>     </tr>      <tr>       <td width="165">|- ntdll.dll!?</td>        <td width="90">4950</td>        <td width="93">4949.49</td>        <td width="141">93.08</td>     </tr>      <tr>       <td width="165">| kernel32.dll!?</td>        <td width="90">4950</td>        <td width="93">4949.49</td>        <td width="141">93.08</td>     </tr>      <tr>       <td width="165">|&#160; |- MSVCR90.DLL!?</td>        <td width="90">4904</td>        <td width="93">4903.486</td>        <td width="141">92.21</td>     </tr>      <tr>       <td width="165">|&#160; |&#160;&#160;&#160; MSVCR90.DLL!?</td>        <td width="90">4904</td>        <td width="93">4903.486</td>        <td width="141">92.21</td>     </tr>      <tr>       <td width="165">|&#160; |&#160;&#160;&#160; MFC90.DLL!?</td>        <td width="90">4904</td>        <td width="93">4903.486</td>        <td width="141">92.21</td>     </tr>      <tr>       <td width="165">|&#160; |&#160;&#160;&#160; FractalX.EXE!?</td>        <td width="90">4904</td>        <td width="93">4903.486</td>        <td width="141">92.21</td>     </tr>      <tr>       <td width="165">|&#160; |&#160;&#160;&#160; FractalX.EXE!?</td>        <td width="90">4904</td>        <td width="93">4903.486</td>        <td width="141">92.21</td>     </tr>      <tr>       <td width="165">|&#160; |&#160;&#160;&#160; FractalX.EXE!?</td>        <td width="90">4904</td>        <td width="93">4903.486</td>        <td width="141">92.21</td>     </tr>      <tr>       <td width="165">|&#160; |&#160; |- FractalX.EXE!?</td>        <td width="90">4900</td>        <td width="93">4899.485</td>        <td width="141">92.14</td>     </tr>      <tr>       <td width="165">|&#160; |&#160; |- user32.dll!?</td>        <td width="90">3</td>        <td width="93">3.001464</td>        <td width="141">0.06</td>     </tr>      <tr>       <td width="165">|&#160; |&#160; |- MSVCR90.DLL!?</td>        <td width="90">1</td>        <td width="93">0.999918</td>        <td width="141">0.02</td>     </tr>      <tr>       <td width="165">|&#160; |- FractalX.EXE!?</td>        <td width="90">46</td>        <td width="93">46.00391</td>        <td width="141">0.87</td>     </tr>      <tr>       <td width="165">|- ntkrnlmp.exe!?</td>        <td width="90">23</td>        <td width="93">23.0229</td>        <td width="141">0.43</td>     </tr>   </tbody></table>  <p>&#160; </p>  <p>A single question mark in the stack column means that no call stack is available at all. If “?!?” is displayed then that means that xperf doesn’t know what executable image was at the address. </p>  <p>If the DLLs are from Microsoft then you should point your symbol path to Microsoft’s symbol servers (using the _NT_SYMBOL_PATH environment variable or Configure Symbol Paths from the Trace menu). You can have multiple symbol paths, separate by semicolons, to that you can point at Microsoft’s symbols and your own simultaneously. Then you need to select Load Symbols from the Trace menu or a graph context menu. </p>  <h3><strong>Exploring Call Stacks</strong></h3>  <p>The call stack display is a bit unusual in that the root of the call stack (conveniently labeled as [Root]) is displayed at the top and you expand downwards from there. The layout is also a bit subtle and non-obvious at first. When you see multiple functions above each other at the same indentation with no minus signs in front of them (for example <strong>endthreadex</strong> and <strong>_AfxThreadEntry</strong> below) then that means that in that section of the call stack all of the collapsed stacks took the same path – <strong>endthreadex</strong> called <strong>_AfxThreadEntry</strong> in all of the samples and these functions have a parent/child relationship. This layout helps to keep the call stack display as compact as possible.</p>  <table border="0" cellspacing="0" cellpadding="0"><tbody>     <tr>       <td width="297">Stack</td>        <td width="64">Count</td>        <td width="64">Weight</td>        <td width="64">% Weight</td>     </tr>      <tr>       <td>[Root]</td>        <td>4973</td>        <td>4972.513</td>        <td>93.51</td>     </tr>      <tr>       <td>|- ntdll.dll!?</td>        <td>4950</td>        <td>4949.49</td>        <td>93.08</td>     </tr>      <tr>       <td>|&#160; kernel32.dll!?</td>        <td>4950</td>        <td>4949.49</td>        <td>93.08</td>     </tr>      <tr>       <td>|&#160; |- MSVCR90.DLL!endthreadex</td>        <td>4904</td>        <td>4903.486</td>        <td>92.21</td>     </tr>      <tr>       <td>|&#160; |&#160;&#160;&#160;&#160; MSVCR90.DLL!endthreadex</td>        <td>4904</td>        <td>4903.486</td>        <td>92.21</td>     </tr>      <tr>       <td>|&#160; |&#160;&#160;&#160;&#160; MFC90.DLL!_AfxThreadEntry</td>        <td>4904</td>        <td>4903.486</td>        <td>92.21</td>     </tr>      <tr>       <td>|&#160; |&#160;&#160;&#160;&#160; FractalX.EXE!PrimaryCalculationProc</td>        <td>4904</td>        <td>4903.486</td>        <td>92.21</td>     </tr>      <tr>       <td>|&#160; |&#160;&#160;&#160;&#160; FractalX.EXE!HomeWork::CalculateNextBit</td>        <td>4904</td>        <td>4903.486</td>        <td>92.21</td>     </tr>      <tr>       <td>|&#160; |&#160; |- FractalX.EXE!Calculator::Calculate</td>        <td>4899</td>        <td>4898.484</td>        <td>92.12</td>     </tr>      <tr>       <td>|&#160; |&#160; |&#160; |- FractalX.EXE!Calculator::Calculate&lt;itself&gt;</td>        <td>2743</td>        <td>2742.873</td>        <td>51.58</td>     </tr>      <tr>       <td>|&#160; |&#160; |&#160; |- FractalX.EXE!Calculator::CalculateHelper</td>        <td>2156</td>        <td>2155.611</td>        <td>40.54</td>     </tr>      <tr>       <td>|&#160; |&#160; |- FractalX.EXE!IterDataImp&lt;int&gt;::Render</td>        <td>5</td>        <td>5.002155</td>        <td>0.09</td>     </tr>      <tr>       <td>|&#160; |- FractalX.EXE!__tmainCRTStartup</td>        <td>46</td>        <td>46.00391</td>        <td>0.87</td>     </tr>   </tbody></table>  <p>&#160; </p>  <p>When you see multiple functions above each other at the same indentation <i>with</i> minus signs in front of them (for instance <strong>Calculator::Calculate</strong> and <strong>IterDataImp&lt;int&gt;::Render</strong>) it means that all of these functions are called by the function above them. In other words those functions are siblings, all called by <strong>HomeWork::CalculateNextBit</strong>, and the collapsed call stacks took multiple paths at this point. </p>  <p>When you see a line that ends with &lt;itself&gt; then than line represents samples that occurred in that function, as opposed to in its descendants. This is often described as the exclusive time, as opposed to inclusive time which includes descendants. The &lt;itself&gt; line for a function, if present, will show up as a child node of the function so that the child nodes’ counts sum up to the parent’s count. In the example above Calculator::Calculate was running for 2743 samples and its child function was running for 2156 samples, for a total of 4899. </p>  <p>The best way to get the feel for how this works is to play around with it. If you select a call stack and repeatedly press the right arrow key then the call stack will keep expanding down the hottest path and this can be a very effective way to drill down into what is probably the most important call stack. </p>  <p>To see call stacks for manifest-based ETW events (assuming you enabled them) you need to go to the Generic Events graph and then select Summary Table from its context menu. From there you should make sure that the Stack column is enabled and you can then explore the stacks. The Count column can be very useful to see how many times the various events were hit from various call stacks. When enabled the stacks of manifest-based events are also available in the tooltips of the corresponding event markers in the Generic graph itself. </p>  <h1><strong>Summary</strong></h1>  <p>Call stacks can be recorded with: </p>  <blockquote>   <table border="0" cellspacing="0" cellpadding="2" width="400"><tbody>       <tr>         <td valign="top" width="400">xperf -on Latency -stackwalk profile</td>       </tr>        <tr>         <td valign="top" width="400">rem Your scenario goes here...</td>       </tr>        <tr>         <td valign="top" width="400">xperf -d mytrace.etl</td>       </tr>     </tbody></table> </blockquote>  <p>If you are tracing on 64-bit Windows don’t forget to set DisablePagingExecutive and then reboot before recording call stacks. And remember that Windows 7 has better ETW call stack recording support than Windows Vista, and Windows XP has no ETW call stack recording support. </p>  <p>To analyze call stacks load the trace into xperfview and look in the appropriate summary table in the Stack column. </p>  <p>Happy tracing! </p>  <p>Bruce Dawson, Windows Client Performance Team </p>]]></content:encoded>
    </item>
    <item>
      <title>StackOverflow answer – why learn multi-core programming? #2</title>
      <link>https://docs.microsoft.com/archive/blogs/pigscanfly/stackoverflow-answer-why-learn-multi-core-programming-2</link>
      <pubDate>Thu, 06 Aug 2009 13:40:00 GMT</pubDate>
      <dc:creator><![CDATA[rgr]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/pigscanfly/2009/08/06/stackoverflow-answer-why-learn-multi-core-programming-2/</guid>
      <description><![CDATA[In my last post I talked about how multi-threading can be used to improve responsiveness while...]]></description>
      <content:encoded><![CDATA[<P>In my <A href="http://blogs.msdn.com/pigscanfly/archive/2009/03/30/stackoverflow-answer-why-learn-multi-core-programming.aspx" target=_blank mce_href="http://blogs.msdn.com/pigscanfly/archive/2009/03/30/stackoverflow-answer-why-learn-multi-core-programming.aspx">last post</A> I talked about how multi-threading can be used to improve responsiveness while loading a file.&nbsp;&nbsp;&nbsp; I’ve put together a sample program (source included) that shows how to do this in C# 3.0, .NET 3.5, and WPF using Visual Studio 2008.&nbsp; You can find a zip file with a complete project attached.</P>
<P>The program has a very simple, but fully functional UI.</P>
<P><A href="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/BlogFileStorage/blogs_msdn/pigscanfly/WindowsLiveWriter/StackOverflowanswerwhylearnmulticoreprog_ED8A/BFE1_4.png" original-url="http://blogs.msdn.com/blogfiles/pigscanfly/WindowsLiveWriter/StackOverflowanswerwhylearnmulticoreprog_ED8A/BFE1_4.png" mce_href="http://blogs.msdn.com/blogfiles/pigscanfly/WindowsLiveWriter/StackOverflowanswerwhylearnmulticoreprog_ED8A/BFE1_4.png"><IMG style="BORDER-RIGHT-WIDTH: 0px; DISPLAY: inline; BORDER-TOP-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; BORDER-LEFT-WIDTH: 0px" title=BFE1 border=0 alt=BFE1 src="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/BlogFileStorage/blogs_msdn/pigscanfly/WindowsLiveWriter/StackOverflowanswerwhylearnmulticoreprog_ED8A/BFE1_thumb_1.png" original-url="http://blogs.msdn.com/blogfiles/pigscanfly/WindowsLiveWriter/StackOverflowanswerwhylearnmulticoreprog_ED8A/BFE1_thumb_1.png" width=383 height=186 mce_src="http://blogs.msdn.com/blogfiles/pigscanfly/WindowsLiveWriter/StackOverflowanswerwhylearnmulticoreprog_ED8A/BFE1_thumb_1.png"></A> </P>
<P>The “Open a file…” pops up the standard open file dialog and ask the user to find a file.&nbsp;&nbsp; The cancel button is disabled unless there is a loading operation to cancel.&nbsp; The text box is for messages from the loader thread and the slider is just there to show that the UI is responsive while the background load occurs.</P>
<P><A href="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/BlogFileStorage/blogs_msdn/pigscanfly/WindowsLiveWriter/StackOverflowanswerwhylearnmulticoreprog_ED8A/BFE2_2.png" original-url="http://blogs.msdn.com/blogfiles/pigscanfly/WindowsLiveWriter/StackOverflowanswerwhylearnmulticoreprog_ED8A/BFE2_2.png" mce_href="http://blogs.msdn.com/blogfiles/pigscanfly/WindowsLiveWriter/StackOverflowanswerwhylearnmulticoreprog_ED8A/BFE2_2.png"><IMG style="BORDER-RIGHT-WIDTH: 0px; DISPLAY: inline; BORDER-TOP-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; BORDER-LEFT-WIDTH: 0px" title=BFE2 border=0 alt=BFE2 src="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/BlogFileStorage/blogs_msdn/pigscanfly/WindowsLiveWriter/StackOverflowanswerwhylearnmulticoreprog_ED8A/BFE2_thumb.png" original-url="http://blogs.msdn.com/blogfiles/pigscanfly/WindowsLiveWriter/StackOverflowanswerwhylearnmulticoreprog_ED8A/BFE2_thumb.png" width=386 height=184 mce_src="http://blogs.msdn.com/blogfiles/pigscanfly/WindowsLiveWriter/StackOverflowanswerwhylearnmulticoreprog_ED8A/BFE2_thumb.png"></A> </P>
<P>The progress bar is hidden unless a file is actually being loaded.&nbsp; If the async check box is un-checked, then the file will be loaded synchronously.&nbsp; This illustrates how the UI will ‘freeze’ if a second thread isn’t used.</P>
<P>The key thing about this program is that the UI stays completely responsive while a file is loaded.&nbsp; Of course, this can be done without threads – many programs are written using a state machine approach.&nbsp; But using threads, and functional programming make this much more simple than previous approaches. </P>
<P>There are many ways to leverage threads in managed code, but the most straight forward way is using the BackgroundWorker class.&nbsp; IT can be used in two ways, by creating one and attaching functions to its delegates, or by creating a new class derived from BackgroundWorker – this is the approach I took here.&nbsp;&nbsp; </P>
<P>I created a class called AsyncFileLoader that is derived from BackgroundWorker.&nbsp; We’re using all the features of BackgroundWorker here</P>
<OL>
<LI>Support for asynchronous progress notifications </LI>
<LI>Support for cancelation </LI>
<LI>Handling of errors during the file loading </LI></OL>
<P>Progress and cancelation is enabled by setting their properties in the constructor.</P>
<DIV id=codeSnippetWrapper>
<DIV style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; PADDING-BOTTOM: 0px; LINE-HEIGHT: 12pt; BORDER-RIGHT-STYLE: none; BACKGROUND-COLOR: #f4f4f4; PADDING-LEFT: 0px; WIDTH: 100%; PADDING-RIGHT: 0px; FONT-FAMILY: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px" id=codeSnippet><PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; PADDING-BOTTOM: 0px; LINE-HEIGHT: 12pt; BORDER-RIGHT-STYLE: none; BACKGROUND-COLOR: white; MARGIN: 0em; PADDING-LEFT: 0px; WIDTH: 100%; PADDING-RIGHT: 0px; FONT-FAMILY: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"><SPAN style="COLOR: #606060" id=lnum1>   1:</SPAN> <SPAN style="COLOR: #0000ff">public</SPAN> AsyncFileLoader()</PRE><!--CRLF--><PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; PADDING-BOTTOM: 0px; LINE-HEIGHT: 12pt; BORDER-RIGHT-STYLE: none; BACKGROUND-COLOR: #f4f4f4; MARGIN: 0em; PADDING-LEFT: 0px; WIDTH: 100%; PADDING-RIGHT: 0px; FONT-FAMILY: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"><SPAN style="COLOR: #606060" id=lnum2>   2:</SPAN> {</PRE><!--CRLF--><PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; PADDING-BOTTOM: 0px; LINE-HEIGHT: 12pt; BORDER-RIGHT-STYLE: none; BACKGROUND-COLOR: white; MARGIN: 0em; PADDING-LEFT: 0px; WIDTH: 100%; PADDING-RIGHT: 0px; FONT-FAMILY: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"><SPAN style="COLOR: #606060" id=lnum3>   3:</SPAN>     WorkerReportsProgress = <SPAN style="COLOR: #0000ff">true</SPAN>;</PRE><!--CRLF--><PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; PADDING-BOTTOM: 0px; LINE-HEIGHT: 12pt; BORDER-RIGHT-STYLE: none; BACKGROUND-COLOR: #f4f4f4; MARGIN: 0em; PADDING-LEFT: 0px; WIDTH: 100%; PADDING-RIGHT: 0px; FONT-FAMILY: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"><SPAN style="COLOR: #606060" id=lnum4>   4:</SPAN>     WorkerSupportsCancellation = <SPAN style="COLOR: #0000ff">true</SPAN>;</PRE><!--CRLF--><PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; PADDING-BOTTOM: 0px; LINE-HEIGHT: 12pt; BORDER-RIGHT-STYLE: none; BACKGROUND-COLOR: white; MARGIN: 0em; PADDING-LEFT: 0px; WIDTH: 100%; PADDING-RIGHT: 0px; FONT-FAMILY: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"><SPAN style="COLOR: #606060" id=lnum5>   5:</SPAN> }</PRE><!--CRLF--></DIV></DIV>
<P>We also need an event handler that will be connected to the cancel button</P>
<DIV id=codeSnippetWrapper>
<DIV style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; PADDING-BOTTOM: 0px; LINE-HEIGHT: 12pt; BORDER-RIGHT-STYLE: none; BACKGROUND-COLOR: #f4f4f4; PADDING-LEFT: 0px; WIDTH: 100%; PADDING-RIGHT: 0px; FONT-FAMILY: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px" id=codeSnippet><PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; PADDING-BOTTOM: 0px; LINE-HEIGHT: 12pt; BORDER-RIGHT-STYLE: none; BACKGROUND-COLOR: white; MARGIN: 0em; PADDING-LEFT: 0px; WIDTH: 100%; PADDING-RIGHT: 0px; FONT-FAMILY: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"><SPAN style="COLOR: #606060" id=lnum1>   1:</SPAN> <SPAN style="COLOR: #0000ff">public</SPAN> <SPAN style="COLOR: #0000ff">void</SPAN> PerformCancel( <SPAN style="COLOR: #0000ff">object</SPAN> sender,  RoutedEventArgs e )</PRE><!--CRLF--><PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; PADDING-BOTTOM: 0px; LINE-HEIGHT: 12pt; BORDER-RIGHT-STYLE: none; BACKGROUND-COLOR: #f4f4f4; MARGIN: 0em; PADDING-LEFT: 0px; WIDTH: 100%; PADDING-RIGHT: 0px; FONT-FAMILY: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"><SPAN style="COLOR: #606060" id=lnum2>   2:</SPAN> {</PRE><!--CRLF--><PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; PADDING-BOTTOM: 0px; LINE-HEIGHT: 12pt; BORDER-RIGHT-STYLE: none; BACKGROUND-COLOR: white; MARGIN: 0em; PADDING-LEFT: 0px; WIDTH: 100%; PADDING-RIGHT: 0px; FONT-FAMILY: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"><SPAN style="COLOR: #606060" id=lnum3>   3:</SPAN>     <SPAN style="COLOR: #0000ff">this</SPAN>.CancelAsync();</PRE><!--CRLF--><PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; PADDING-BOTTOM: 0px; LINE-HEIGHT: 12pt; BORDER-RIGHT-STYLE: none; BACKGROUND-COLOR: #f4f4f4; MARGIN: 0em; PADDING-LEFT: 0px; WIDTH: 100%; PADDING-RIGHT: 0px; FONT-FAMILY: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"><SPAN style="COLOR: #606060" id=lnum4>   4:</SPAN> }</PRE><!--CRLF--></DIV></DIV>
<P>The final element is a function that overrides BackgroundWorker.OnDoWork().&nbsp;&nbsp; This function does all the work of asynchronously loading a text file.</P>
<DIV id=codeSnippetWrapper>
<DIV style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; PADDING-BOTTOM: 0px; LINE-HEIGHT: 12pt; BORDER-RIGHT-STYLE: none; BACKGROUND-COLOR: #f4f4f4; PADDING-LEFT: 0px; WIDTH: 100%; PADDING-RIGHT: 0px; FONT-FAMILY: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px" id=codeSnippet><PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; PADDING-BOTTOM: 0px; LINE-HEIGHT: 12pt; BORDER-RIGHT-STYLE: none; BACKGROUND-COLOR: white; MARGIN: 0em; PADDING-LEFT: 0px; WIDTH: 100%; PADDING-RIGHT: 0px; FONT-FAMILY: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"><SPAN style="COLOR: #606060" id=lnum1>   1:</SPAN> <SPAN style="COLOR: #0000ff">protected</SPAN> <SPAN style="COLOR: #0000ff">override</SPAN> <SPAN style="COLOR: #0000ff">void</SPAN> OnDoWork( DoWorkEventArgs e )</PRE><!--CRLF--><PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; PADDING-BOTTOM: 0px; LINE-HEIGHT: 12pt; BORDER-RIGHT-STYLE: none; BACKGROUND-COLOR: #f4f4f4; MARGIN: 0em; PADDING-LEFT: 0px; WIDTH: 100%; PADDING-RIGHT: 0px; FONT-FAMILY: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"><SPAN style="COLOR: #606060" id=lnum2>   2:</SPAN> {</PRE><!--CRLF--><PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; PADDING-BOTTOM: 0px; LINE-HEIGHT: 12pt; BORDER-RIGHT-STYLE: none; BACKGROUND-COLOR: white; MARGIN: 0em; PADDING-LEFT: 0px; WIDTH: 100%; PADDING-RIGHT: 0px; FONT-FAMILY: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"><SPAN style="COLOR: #606060" id=lnum3>   3:</SPAN>     <SPAN style="COLOR: #008000">// note: do not catch exceptions here.  The BackgroundWorker will catch exceptions </SPAN></PRE><!--CRLF--><PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; PADDING-BOTTOM: 0px; LINE-HEIGHT: 12pt; BORDER-RIGHT-STYLE: none; BACKGROUND-COLOR: #f4f4f4; MARGIN: 0em; PADDING-LEFT: 0px; WIDTH: 100%; PADDING-RIGHT: 0px; FONT-FAMILY: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"><SPAN style="COLOR: #606060" id=lnum4>   4:</SPAN>     <SPAN style="COLOR: #008000">// and pass them back to the initiating thread in the RunWorkerCompleted() delegate </SPAN></PRE><!--CRLF--><PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; PADDING-BOTTOM: 0px; LINE-HEIGHT: 12pt; BORDER-RIGHT-STYLE: none; BACKGROUND-COLOR: white; MARGIN: 0em; PADDING-LEFT: 0px; WIDTH: 100%; PADDING-RIGHT: 0px; FONT-FAMILY: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"><SPAN style="COLOR: #606060" id=lnum5>   5:</SPAN>     <SPAN style="COLOR: #008000">// using the error member of RunWorkerCompletedEventArgs parameter.</SPAN></PRE><!--CRLF--><PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; PADDING-BOTTOM: 0px; LINE-HEIGHT: 12pt; BORDER-RIGHT-STYLE: none; BACKGROUND-COLOR: #f4f4f4; MARGIN: 0em; PADDING-LEFT: 0px; WIDTH: 100%; PADDING-RIGHT: 0px; FONT-FAMILY: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"><SPAN style="COLOR: #606060" id=lnum6>   6:</SPAN>&nbsp; </PRE><!--CRLF--><PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; PADDING-BOTTOM: 0px; LINE-HEIGHT: 12pt; BORDER-RIGHT-STYLE: none; BACKGROUND-COLOR: white; MARGIN: 0em; PADDING-LEFT: 0px; WIDTH: 100%; PADDING-RIGHT: 0px; FONT-FAMILY: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"><SPAN style="COLOR: #606060" id=lnum7>   7:</SPAN>     <SPAN style="COLOR: #0000ff">string</SPAN> FileName = e.Argument <SPAN style="COLOR: #0000ff">as</SPAN> <SPAN style="COLOR: #0000ff">string</SPAN>;</PRE><!--CRLF--><PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; PADDING-BOTTOM: 0px; LINE-HEIGHT: 12pt; BORDER-RIGHT-STYLE: none; BACKGROUND-COLOR: #f4f4f4; MARGIN: 0em; PADDING-LEFT: 0px; WIDTH: 100%; PADDING-RIGHT: 0px; FONT-FAMILY: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"><SPAN style="COLOR: #606060" id=lnum8>   8:</SPAN>&nbsp; </PRE><!--CRLF--><PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; PADDING-BOTTOM: 0px; LINE-HEIGHT: 12pt; BORDER-RIGHT-STYLE: none; BACKGROUND-COLOR: white; MARGIN: 0em; PADDING-LEFT: 0px; WIDTH: 100%; PADDING-RIGHT: 0px; FONT-FAMILY: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"><SPAN style="COLOR: #606060" id=lnum9>   9:</SPAN>     ReportProgress( <SPAN style="COLOR: #0000ff">int</SPAN>.MinValue, String.Format( <SPAN style="COLOR: #006080">"Opening {0}"</SPAN>, FileName ) );</PRE><!--CRLF--><PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; PADDING-BOTTOM: 0px; LINE-HEIGHT: 12pt; BORDER-RIGHT-STYLE: none; BACKGROUND-COLOR: #f4f4f4; MARGIN: 0em; PADDING-LEFT: 0px; WIDTH: 100%; PADDING-RIGHT: 0px; FONT-FAMILY: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"><SPAN style="COLOR: #606060" id=lnum10>  10:</SPAN>&nbsp; </PRE><!--CRLF--><PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; PADDING-BOTTOM: 0px; LINE-HEIGHT: 12pt; BORDER-RIGHT-STYLE: none; BACKGROUND-COLOR: white; MARGIN: 0em; PADDING-LEFT: 0px; WIDTH: 100%; PADDING-RIGHT: 0px; FONT-FAMILY: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"><SPAN style="COLOR: #606060" id=lnum11>  11:</SPAN>     <SPAN style="COLOR: #0000ff">using</SPAN> ( StreamReader sr = <SPAN style="COLOR: #0000ff">new</SPAN> StreamReader( FileName, Encoding.UTF8 ) ) </PRE><!--CRLF--><PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; PADDING-BOTTOM: 0px; LINE-HEIGHT: 12pt; BORDER-RIGHT-STYLE: none; BACKGROUND-COLOR: #f4f4f4; MARGIN: 0em; PADDING-LEFT: 0px; WIDTH: 100%; PADDING-RIGHT: 0px; FONT-FAMILY: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"><SPAN style="COLOR: #606060" id=lnum12>  12:</SPAN>     {</PRE><!--CRLF--><PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; PADDING-BOTTOM: 0px; LINE-HEIGHT: 12pt; BORDER-RIGHT-STYLE: none; BACKGROUND-COLOR: white; MARGIN: 0em; PADDING-LEFT: 0px; WIDTH: 100%; PADDING-RIGHT: 0px; FONT-FAMILY: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"><SPAN style="COLOR: #606060" id=lnum13>  13:</SPAN>         ReportProgress( <SPAN style="COLOR: #0000ff">int</SPAN>.MinValue, String.Format( <SPAN style="COLOR: #006080">"Loading {0}"</SPAN>, FileName ) );</PRE><!--CRLF--><PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; PADDING-BOTTOM: 0px; LINE-HEIGHT: 12pt; BORDER-RIGHT-STYLE: none; BACKGROUND-COLOR: #f4f4f4; MARGIN: 0em; PADDING-LEFT: 0px; WIDTH: 100%; PADDING-RIGHT: 0px; FONT-FAMILY: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"><SPAN style="COLOR: #606060" id=lnum14>  14:</SPAN>&nbsp; </PRE><!--CRLF--><PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; PADDING-BOTTOM: 0px; LINE-HEIGHT: 12pt; BORDER-RIGHT-STYLE: none; BACKGROUND-COLOR: white; MARGIN: 0em; PADDING-LEFT: 0px; WIDTH: 100%; PADDING-RIGHT: 0px; FONT-FAMILY: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"><SPAN style="COLOR: #606060" id=lnum15>  15:</SPAN>         <SPAN style="COLOR: #0000ff">long</SPAN> FileLength = sr.BaseStream.Length;</PRE><!--CRLF--><PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; PADDING-BOTTOM: 0px; LINE-HEIGHT: 12pt; BORDER-RIGHT-STYLE: none; BACKGROUND-COLOR: #f4f4f4; MARGIN: 0em; PADDING-LEFT: 0px; WIDTH: 100%; PADDING-RIGHT: 0px; FONT-FAMILY: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"><SPAN style="COLOR: #606060" id=lnum16>  16:</SPAN>         <SPAN style="COLOR: #0000ff">long</SPAN> PercentRead = 0;</PRE><!--CRLF--><PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; PADDING-BOTTOM: 0px; LINE-HEIGHT: 12pt; BORDER-RIGHT-STYLE: none; BACKGROUND-COLOR: white; MARGIN: 0em; PADDING-LEFT: 0px; WIDTH: 100%; PADDING-RIGHT: 0px; FONT-FAMILY: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"><SPAN style="COLOR: #606060" id=lnum17>  17:</SPAN>         <SPAN style="COLOR: #0000ff">long</SPAN> LastPercentRead = 0;</PRE><!--CRLF--><PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; PADDING-BOTTOM: 0px; LINE-HEIGHT: 12pt; BORDER-RIGHT-STYLE: none; BACKGROUND-COLOR: #f4f4f4; MARGIN: 0em; PADDING-LEFT: 0px; WIDTH: 100%; PADDING-RIGHT: 0px; FONT-FAMILY: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"><SPAN style="COLOR: #606060" id=lnum18>  18:</SPAN>&nbsp; </PRE><!--CRLF--><PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; PADDING-BOTTOM: 0px; LINE-HEIGHT: 12pt; BORDER-RIGHT-STYLE: none; BACKGROUND-COLOR: white; MARGIN: 0em; PADDING-LEFT: 0px; WIDTH: 100%; PADDING-RIGHT: 0px; FONT-FAMILY: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"><SPAN style="COLOR: #606060" id=lnum19>  19:</SPAN>         String line;</PRE><!--CRLF--><PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; PADDING-BOTTOM: 0px; LINE-HEIGHT: 12pt; BORDER-RIGHT-STYLE: none; BACKGROUND-COLOR: #f4f4f4; MARGIN: 0em; PADDING-LEFT: 0px; WIDTH: 100%; PADDING-RIGHT: 0px; FONT-FAMILY: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"><SPAN style="COLOR: #606060" id=lnum20>  20:</SPAN>&nbsp; </PRE><!--CRLF--><PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; PADDING-BOTTOM: 0px; LINE-HEIGHT: 12pt; BORDER-RIGHT-STYLE: none; BACKGROUND-COLOR: white; MARGIN: 0em; PADDING-LEFT: 0px; WIDTH: 100%; PADDING-RIGHT: 0px; FONT-FAMILY: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"><SPAN style="COLOR: #606060" id=lnum21>  21:</SPAN>         <SPAN style="COLOR: #0000ff">while</SPAN> ( (line = sr.ReadLine()) != <SPAN style="COLOR: #0000ff">null</SPAN> ) {</PRE><!--CRLF--><PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; PADDING-BOTTOM: 0px; LINE-HEIGHT: 12pt; BORDER-RIGHT-STYLE: none; BACKGROUND-COLOR: #f4f4f4; MARGIN: 0em; PADDING-LEFT: 0px; WIDTH: 100%; PADDING-RIGHT: 0px; FONT-FAMILY: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"><SPAN style="COLOR: #606060" id=lnum22>  22:</SPAN>&nbsp; </PRE><!--CRLF--><PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; PADDING-BOTTOM: 0px; LINE-HEIGHT: 12pt; BORDER-RIGHT-STYLE: none; BACKGROUND-COLOR: white; MARGIN: 0em; PADDING-LEFT: 0px; WIDTH: 100%; PADDING-RIGHT: 0px; FONT-FAMILY: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"><SPAN style="COLOR: #606060" id=lnum23>  23:</SPAN>             <SPAN style="COLOR: #0000ff">if</SPAN> ( CancellationPending ) {</PRE><!--CRLF--><PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; PADDING-BOTTOM: 0px; LINE-HEIGHT: 12pt; BORDER-RIGHT-STYLE: none; BACKGROUND-COLOR: #f4f4f4; MARGIN: 0em; PADDING-LEFT: 0px; WIDTH: 100%; PADDING-RIGHT: 0px; FONT-FAMILY: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"><SPAN style="COLOR: #606060" id=lnum24>  24:</SPAN>                 e.Cancel = <SPAN style="COLOR: #0000ff">true</SPAN>;</PRE><!--CRLF--><PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; PADDING-BOTTOM: 0px; LINE-HEIGHT: 12pt; BORDER-RIGHT-STYLE: none; BACKGROUND-COLOR: white; MARGIN: 0em; PADDING-LEFT: 0px; WIDTH: 100%; PADDING-RIGHT: 0px; FONT-FAMILY: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"><SPAN style="COLOR: #606060" id=lnum25>  25:</SPAN>                 <SPAN style="COLOR: #0000ff">break</SPAN>;</PRE><!--CRLF--><PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; PADDING-BOTTOM: 0px; LINE-HEIGHT: 12pt; BORDER-RIGHT-STYLE: none; BACKGROUND-COLOR: #f4f4f4; MARGIN: 0em; PADDING-LEFT: 0px; WIDTH: 100%; PADDING-RIGHT: 0px; FONT-FAMILY: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"><SPAN style="COLOR: #606060" id=lnum26>  26:</SPAN>             }</PRE><!--CRLF--><PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; PADDING-BOTTOM: 0px; LINE-HEIGHT: 12pt; BORDER-RIGHT-STYLE: none; BACKGROUND-COLOR: white; MARGIN: 0em; PADDING-LEFT: 0px; WIDTH: 100%; PADDING-RIGHT: 0px; FONT-FAMILY: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"><SPAN style="COLOR: #606060" id=lnum27>  27:</SPAN>&nbsp; </PRE><!--CRLF--><PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; PADDING-BOTTOM: 0px; LINE-HEIGHT: 12pt; BORDER-RIGHT-STYLE: none; BACKGROUND-COLOR: #f4f4f4; MARGIN: 0em; PADDING-LEFT: 0px; WIDTH: 100%; PADDING-RIGHT: 0px; FONT-FAMILY: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"><SPAN style="COLOR: #606060" id=lnum28>  28:</SPAN>             PercentRead = (sr.BaseStream.Position * 100) / FileLength;</PRE><!--CRLF--><PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; PADDING-BOTTOM: 0px; LINE-HEIGHT: 12pt; BORDER-RIGHT-STYLE: none; BACKGROUND-COLOR: white; MARGIN: 0em; PADDING-LEFT: 0px; WIDTH: 100%; PADDING-RIGHT: 0px; FONT-FAMILY: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"><SPAN style="COLOR: #606060" id=lnum29>  29:</SPAN>&nbsp; </PRE><!--CRLF--><PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; PADDING-BOTTOM: 0px; LINE-HEIGHT: 12pt; BORDER-RIGHT-STYLE: none; BACKGROUND-COLOR: #f4f4f4; MARGIN: 0em; PADDING-LEFT: 0px; WIDTH: 100%; PADDING-RIGHT: 0px; FONT-FAMILY: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"><SPAN style="COLOR: #606060" id=lnum30>  30:</SPAN>             <SPAN style="COLOR: #0000ff">if</SPAN> ( PercentRead &gt;= LastPercentRead + 1 ) {</PRE><!--CRLF--><PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; PADDING-BOTTOM: 0px; LINE-HEIGHT: 12pt; BORDER-RIGHT-STYLE: none; BACKGROUND-COLOR: white; MARGIN: 0em; PADDING-LEFT: 0px; WIDTH: 100%; PADDING-RIGHT: 0px; FONT-FAMILY: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"><SPAN style="COLOR: #606060" id=lnum31>  31:</SPAN>                 ReportProgress( (<SPAN style="COLOR: #0000ff">int</SPAN>)PercentRead );</PRE><!--CRLF--><PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; PADDING-BOTTOM: 0px; LINE-HEIGHT: 12pt; BORDER-RIGHT-STYLE: none; BACKGROUND-COLOR: #f4f4f4; MARGIN: 0em; PADDING-LEFT: 0px; WIDTH: 100%; PADDING-RIGHT: 0px; FONT-FAMILY: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"><SPAN style="COLOR: #606060" id=lnum32>  32:</SPAN>                 LastPercentRead = PercentRead;</PRE><!--CRLF--><PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; PADDING-BOTTOM: 0px; LINE-HEIGHT: 12pt; BORDER-RIGHT-STYLE: none; BACKGROUND-COLOR: white; MARGIN: 0em; PADDING-LEFT: 0px; WIDTH: 100%; PADDING-RIGHT: 0px; FONT-FAMILY: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"><SPAN style="COLOR: #606060" id=lnum33>  33:</SPAN>             }</PRE><!--CRLF--><PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; PADDING-BOTTOM: 0px; LINE-HEIGHT: 12pt; BORDER-RIGHT-STYLE: none; BACKGROUND-COLOR: #f4f4f4; MARGIN: 0em; PADDING-LEFT: 0px; WIDTH: 100%; PADDING-RIGHT: 0px; FONT-FAMILY: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"><SPAN style="COLOR: #606060" id=lnum34>  34:</SPAN>         }</PRE><!--CRLF--><PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; PADDING-BOTTOM: 0px; LINE-HEIGHT: 12pt; BORDER-RIGHT-STYLE: none; BACKGROUND-COLOR: white; MARGIN: 0em; PADDING-LEFT: 0px; WIDTH: 100%; PADDING-RIGHT: 0px; FONT-FAMILY: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"><SPAN style="COLOR: #606060" id=lnum35>  35:</SPAN>     }</PRE><!--CRLF--><PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; PADDING-BOTTOM: 0px; LINE-HEIGHT: 12pt; BORDER-RIGHT-STYLE: none; BACKGROUND-COLOR: #f4f4f4; MARGIN: 0em; PADDING-LEFT: 0px; WIDTH: 100%; PADDING-RIGHT: 0px; FONT-FAMILY: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"><SPAN style="COLOR: #606060" id=lnum36>  36:</SPAN> }</PRE><!--CRLF--></DIV></DIV>
<P>As you can see – this is really simple, and most important procedural – there isn’t a state machine, or any explicitly state kept at all.&nbsp; This single function loads the file, and sends progress messages and errors asynchronously to the calling thread. </P>
<P>The initiating thread passes the background thread parameters using the DoWorkEventArgs class.&nbsp; Here, I’ve simply passed the file name as a string, but any class or structure could be passed this way.</P>
<P>Line 9 is important – it asynchronously passes the first progress message back to the main thread.&nbsp;&nbsp; This includes the progress percentage and the name of the file.&nbsp; Here I’m using <STRONG>int.MinValue</STRONG> to differentiate the first progress message from subsequent ones.&nbsp; This sentinel value means that the main thread doesn’t have to maintain any state to handle progress messages. </P>
<P>I mentioned above that this function handles errors, but you don’t see any error handling code!&nbsp; Any errors that occur from opening the file, or reading the data are signaled as exceptions.&nbsp; The BackgroundWorker class will catch these and pass them back tot he main thread.&nbsp; I just love this – it keeps the code here very clean.</P>
<P>Note the using statement on line 11.&nbsp; It is important to do this when using file I/O objects so the underlying OS objects get cleaned up correctly.&nbsp; See <A href="http://msdn.microsoft.com/en-us/library/system.idisposable.dispose.aspx" target=_blank mce_href="http://msdn.microsoft.com/en-us/library/system.idisposable.dispose.aspx">this</A> for more information.</P>
<P>The progress percentage value is computed very simply, the code simply keeps track of the file position as a ration to the file size.&nbsp; This is the obvious part.</P>
<P>Note line 30 – this is very important.&nbsp; It only sends progress messages to the main thread when the value changes – not for every line, which would be quite expensive (give it a try to see).</P>
<P>The entire AsyncFileLoader.cs file is not very big, only 29 lines of actual code and is very straightforward. </P>
<P>The code in the main thread to mange the UI is equally straight forward and consists of just a single event handler attached to the open button’s click delegate.&nbsp; This one function does all of the following:</P>
<OL>
<LI>Gets the file name from the user using the open file dialog. </LI>
<LI>Maintains the UI state, disable buttons,&nbsp; showing/hiding the progress bar, displaying messages, etc. </LI>
<LI>Creates a the AsyncFileLoader object </LI>
<LI>Starts the asynchronous file loading operation </LI>
<LI>Handles progress messages </LI>
<LI>handles the completion of the operation </LI>
<LI>Handles errors. </LI></OL>
<DIV id=codeSnippetWrapper>
<DIV style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; PADDING-BOTTOM: 0px; LINE-HEIGHT: 12pt; BORDER-RIGHT-STYLE: none; BACKGROUND-COLOR: #f4f4f4; PADDING-LEFT: 0px; WIDTH: 100%; PADDING-RIGHT: 0px; FONT-FAMILY: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px" id=codeSnippet><PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; PADDING-BOTTOM: 0px; LINE-HEIGHT: 12pt; BORDER-RIGHT-STYLE: none; BACKGROUND-COLOR: white; MARGIN: 0em; PADDING-LEFT: 0px; WIDTH: 100%; PADDING-RIGHT: 0px; FONT-FAMILY: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"><SPAN style="COLOR: #606060" id=lnum1>   1:</SPAN> <SPAN style="COLOR: #0000ff">private</SPAN> <SPAN style="COLOR: #0000ff">void</SPAN> OpenAFile_Clicked( <SPAN style="COLOR: #0000ff">object</SPAN> sender, RoutedEventArgs e )</PRE><!--CRLF--><PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; PADDING-BOTTOM: 0px; LINE-HEIGHT: 12pt; BORDER-RIGHT-STYLE: none; BACKGROUND-COLOR: #f4f4f4; MARGIN: 0em; PADDING-LEFT: 0px; WIDTH: 100%; PADDING-RIGHT: 0px; FONT-FAMILY: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"><SPAN style="COLOR: #606060" id=lnum2>   2:</SPAN> {</PRE><!--CRLF--><PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; PADDING-BOTTOM: 0px; LINE-HEIGHT: 12pt; BORDER-RIGHT-STYLE: none; BACKGROUND-COLOR: white; MARGIN: 0em; PADDING-LEFT: 0px; WIDTH: 100%; PADDING-RIGHT: 0px; FONT-FAMILY: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"><SPAN style="COLOR: #606060" id=lnum3>   3:</SPAN>     <SPAN style="COLOR: #0000ff">try</SPAN> {</PRE><!--CRLF--><PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; PADDING-BOTTOM: 0px; LINE-HEIGHT: 12pt; BORDER-RIGHT-STYLE: none; BACKGROUND-COLOR: #f4f4f4; MARGIN: 0em; PADDING-LEFT: 0px; WIDTH: 100%; PADDING-RIGHT: 0px; FONT-FAMILY: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"><SPAN style="COLOR: #606060" id=lnum4>   4:</SPAN>         OpenFileDialog ofd = <SPAN style="COLOR: #0000ff">new</SPAN> OpenFileDialog();</PRE><!--CRLF--><PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; PADDING-BOTTOM: 0px; LINE-HEIGHT: 12pt; BORDER-RIGHT-STYLE: none; BACKGROUND-COLOR: white; MARGIN: 0em; PADDING-LEFT: 0px; WIDTH: 100%; PADDING-RIGHT: 0px; FONT-FAMILY: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"><SPAN style="COLOR: #606060" id=lnum5>   5:</SPAN>         ofd.CheckFileExists = <SPAN style="COLOR: #0000ff">true</SPAN>;</PRE><!--CRLF--><PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; PADDING-BOTTOM: 0px; LINE-HEIGHT: 12pt; BORDER-RIGHT-STYLE: none; BACKGROUND-COLOR: #f4f4f4; MARGIN: 0em; PADDING-LEFT: 0px; WIDTH: 100%; PADDING-RIGHT: 0px; FONT-FAMILY: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"><SPAN style="COLOR: #606060" id=lnum6>   6:</SPAN>         ofd.DefaultExt = <SPAN style="COLOR: #006080">"txt"</SPAN>;</PRE><!--CRLF--><PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; PADDING-BOTTOM: 0px; LINE-HEIGHT: 12pt; BORDER-RIGHT-STYLE: none; BACKGROUND-COLOR: white; MARGIN: 0em; PADDING-LEFT: 0px; WIDTH: 100%; PADDING-RIGHT: 0px; FONT-FAMILY: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"><SPAN style="COLOR: #606060" id=lnum7>   7:</SPAN>         ofd.Title = <SPAN style="COLOR: #006080">"Open an text File"</SPAN>;</PRE><!--CRLF--><PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; PADDING-BOTTOM: 0px; LINE-HEIGHT: 12pt; BORDER-RIGHT-STYLE: none; BACKGROUND-COLOR: #f4f4f4; MARGIN: 0em; PADDING-LEFT: 0px; WIDTH: 100%; PADDING-RIGHT: 0px; FONT-FAMILY: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"><SPAN style="COLOR: #606060" id=lnum8>   8:</SPAN>         ofd.Filter = <SPAN style="COLOR: #006080">"Text|*.txt"</SPAN>;</PRE><!--CRLF--><PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; PADDING-BOTTOM: 0px; LINE-HEIGHT: 12pt; BORDER-RIGHT-STYLE: none; BACKGROUND-COLOR: white; MARGIN: 0em; PADDING-LEFT: 0px; WIDTH: 100%; PADDING-RIGHT: 0px; FONT-FAMILY: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"><SPAN style="COLOR: #606060" id=lnum9>   9:</SPAN>&nbsp; </PRE><!--CRLF--><PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; PADDING-BOTTOM: 0px; LINE-HEIGHT: 12pt; BORDER-RIGHT-STYLE: none; BACKGROUND-COLOR: #f4f4f4; MARGIN: 0em; PADDING-LEFT: 0px; WIDTH: 100%; PADDING-RIGHT: 0px; FONT-FAMILY: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"><SPAN style="COLOR: #606060" id=lnum10>  10:</SPAN>         OpenAFile_Button.IsEnabled = <SPAN style="COLOR: #0000ff">false</SPAN>;</PRE><!--CRLF--><PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; PADDING-BOTTOM: 0px; LINE-HEIGHT: 12pt; BORDER-RIGHT-STYLE: none; BACKGROUND-COLOR: white; MARGIN: 0em; PADDING-LEFT: 0px; WIDTH: 100%; PADDING-RIGHT: 0px; FONT-FAMILY: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"><SPAN style="COLOR: #606060" id=lnum11>  11:</SPAN>&nbsp; </PRE><!--CRLF--><PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; PADDING-BOTTOM: 0px; LINE-HEIGHT: 12pt; BORDER-RIGHT-STYLE: none; BACKGROUND-COLOR: #f4f4f4; MARGIN: 0em; PADDING-LEFT: 0px; WIDTH: 100%; PADDING-RIGHT: 0px; FONT-FAMILY: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"><SPAN style="COLOR: #606060" id=lnum12>  12:</SPAN>         ofd.ShowDialog();</PRE><!--CRLF--><PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; PADDING-BOTTOM: 0px; LINE-HEIGHT: 12pt; BORDER-RIGHT-STYLE: none; BACKGROUND-COLOR: white; MARGIN: 0em; PADDING-LEFT: 0px; WIDTH: 100%; PADDING-RIGHT: 0px; FONT-FAMILY: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"><SPAN style="COLOR: #606060" id=lnum13>  13:</SPAN>&nbsp; </PRE><!--CRLF--><PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; PADDING-BOTTOM: 0px; LINE-HEIGHT: 12pt; BORDER-RIGHT-STYLE: none; BACKGROUND-COLOR: #f4f4f4; MARGIN: 0em; PADDING-LEFT: 0px; WIDTH: 100%; PADDING-RIGHT: 0px; FONT-FAMILY: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"><SPAN style="COLOR: #606060" id=lnum14>  14:</SPAN>         <SPAN style="COLOR: #0000ff">if</SPAN> ( ofd.FileName.IsBlank() ) {</PRE><!--CRLF--><PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; PADDING-BOTTOM: 0px; LINE-HEIGHT: 12pt; BORDER-RIGHT-STYLE: none; BACKGROUND-COLOR: white; MARGIN: 0em; PADDING-LEFT: 0px; WIDTH: 100%; PADDING-RIGHT: 0px; FONT-FAMILY: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"><SPAN style="COLOR: #606060" id=lnum15>  15:</SPAN>             OpenAFile_Button.IsEnabled = <SPAN style="COLOR: #0000ff">true</SPAN>;</PRE><!--CRLF--><PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; PADDING-BOTTOM: 0px; LINE-HEIGHT: 12pt; BORDER-RIGHT-STYLE: none; BACKGROUND-COLOR: #f4f4f4; MARGIN: 0em; PADDING-LEFT: 0px; WIDTH: 100%; PADDING-RIGHT: 0px; FONT-FAMILY: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"><SPAN style="COLOR: #606060" id=lnum16>  16:</SPAN>             <SPAN style="COLOR: #0000ff">return</SPAN>;</PRE><!--CRLF--><PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; PADDING-BOTTOM: 0px; LINE-HEIGHT: 12pt; BORDER-RIGHT-STYLE: none; BACKGROUND-COLOR: white; MARGIN: 0em; PADDING-LEFT: 0px; WIDTH: 100%; PADDING-RIGHT: 0px; FONT-FAMILY: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"><SPAN style="COLOR: #606060" id=lnum17>  17:</SPAN>         }</PRE><!--CRLF--><PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; PADDING-BOTTOM: 0px; LINE-HEIGHT: 12pt; BORDER-RIGHT-STYLE: none; BACKGROUND-COLOR: #f4f4f4; MARGIN: 0em; PADDING-LEFT: 0px; WIDTH: 100%; PADDING-RIGHT: 0px; FONT-FAMILY: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"><SPAN style="COLOR: #606060" id=lnum18>  18:</SPAN>&nbsp; </PRE><!--CRLF--><PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; PADDING-BOTTOM: 0px; LINE-HEIGHT: 12pt; BORDER-RIGHT-STYLE: none; BACKGROUND-COLOR: white; MARGIN: 0em; PADDING-LEFT: 0px; WIDTH: 100%; PADDING-RIGHT: 0px; FONT-FAMILY: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"><SPAN style="COLOR: #606060" id=lnum19>  19:</SPAN>         AsyncFileLoader TheLoader = <SPAN style="COLOR: #0000ff">new</SPAN> AsyncFileLoader();</PRE><!--CRLF--><PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; PADDING-BOTTOM: 0px; LINE-HEIGHT: 12pt; BORDER-RIGHT-STYLE: none; BACKGROUND-COLOR: #f4f4f4; MARGIN: 0em; PADDING-LEFT: 0px; WIDTH: 100%; PADDING-RIGHT: 0px; FONT-FAMILY: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"><SPAN style="COLOR: #606060" id=lnum20>  20:</SPAN>&nbsp; </PRE><!--CRLF--><PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; PADDING-BOTTOM: 0px; LINE-HEIGHT: 12pt; BORDER-RIGHT-STYLE: none; BACKGROUND-COLOR: white; MARGIN: 0em; PADDING-LEFT: 0px; WIDTH: 100%; PADDING-RIGHT: 0px; FONT-FAMILY: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"><SPAN style="COLOR: #606060" id=lnum21>  21:</SPAN>         <SPAN style="COLOR: #008000">//---- Do this when the progress bar is updated</SPAN></PRE><!--CRLF--><PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; PADDING-BOTTOM: 0px; LINE-HEIGHT: 12pt; BORDER-RIGHT-STYLE: none; BACKGROUND-COLOR: #f4f4f4; MARGIN: 0em; PADDING-LEFT: 0px; WIDTH: 100%; PADDING-RIGHT: 0px; FONT-FAMILY: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"><SPAN style="COLOR: #606060" id=lnum22>  22:</SPAN>         TheLoader.ProgressChanged += ( Sender, ArgsX ) =&gt; {</PRE><!--CRLF--><PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; PADDING-BOTTOM: 0px; LINE-HEIGHT: 12pt; BORDER-RIGHT-STYLE: none; BACKGROUND-COLOR: white; MARGIN: 0em; PADDING-LEFT: 0px; WIDTH: 100%; PADDING-RIGHT: 0px; FONT-FAMILY: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"><SPAN style="COLOR: #606060" id=lnum23>  23:</SPAN>&nbsp; </PRE><!--CRLF--><PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; PADDING-BOTTOM: 0px; LINE-HEIGHT: 12pt; BORDER-RIGHT-STYLE: none; BACKGROUND-COLOR: #f4f4f4; MARGIN: 0em; PADDING-LEFT: 0px; WIDTH: 100%; PADDING-RIGHT: 0px; FONT-FAMILY: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"><SPAN style="COLOR: #606060" id=lnum24>  24:</SPAN>             <SPAN style="COLOR: #0000ff">if</SPAN> ( ArgsX.ProgressPercentage == <SPAN style="COLOR: #0000ff">int</SPAN>.MinValue ) {</PRE><!--CRLF--><PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; PADDING-BOTTOM: 0px; LINE-HEIGHT: 12pt; BORDER-RIGHT-STYLE: none; BACKGROUND-COLOR: white; MARGIN: 0em; PADDING-LEFT: 0px; WIDTH: 100%; PADDING-RIGHT: 0px; FONT-FAMILY: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"><SPAN style="COLOR: #606060" id=lnum25>  25:</SPAN>                 Cancel_Button.IsEnabled = <SPAN style="COLOR: #0000ff">true</SPAN>;</PRE><!--CRLF--><PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; PADDING-BOTTOM: 0px; LINE-HEIGHT: 12pt; BORDER-RIGHT-STYLE: none; BACKGROUND-COLOR: #f4f4f4; MARGIN: 0em; PADDING-LEFT: 0px; WIDTH: 100%; PADDING-RIGHT: 0px; FONT-FAMILY: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"><SPAN style="COLOR: #606060" id=lnum26>  26:</SPAN>                 Cancel_Button.Click += TheLoader.PerformCancel;</PRE><!--CRLF--><PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; PADDING-BOTTOM: 0px; LINE-HEIGHT: 12pt; BORDER-RIGHT-STYLE: none; BACKGROUND-COLOR: white; MARGIN: 0em; PADDING-LEFT: 0px; WIDTH: 100%; PADDING-RIGHT: 0px; FONT-FAMILY: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"><SPAN style="COLOR: #606060" id=lnum27>  27:</SPAN>                 OpenProgress_ProgressBar.IsEnabled = <SPAN style="COLOR: #0000ff">true</SPAN>;</PRE><!--CRLF--><PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; PADDING-BOTTOM: 0px; LINE-HEIGHT: 12pt; BORDER-RIGHT-STYLE: none; BACKGROUND-COLOR: #f4f4f4; MARGIN: 0em; PADDING-LEFT: 0px; WIDTH: 100%; PADDING-RIGHT: 0px; FONT-FAMILY: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"><SPAN style="COLOR: #606060" id=lnum28>  28:</SPAN>                 OpenProgress_ProgressBar.Visibility = Visibility.Visible;</PRE><!--CRLF--><PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; PADDING-BOTTOM: 0px; LINE-HEIGHT: 12pt; BORDER-RIGHT-STYLE: none; BACKGROUND-COLOR: white; MARGIN: 0em; PADDING-LEFT: 0px; WIDTH: 100%; PADDING-RIGHT: 0px; FONT-FAMILY: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"><SPAN style="COLOR: #606060" id=lnum29>  29:</SPAN>                 OpenProgress_ProgressBar.Value = 0;</PRE><!--CRLF--><PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; PADDING-BOTTOM: 0px; LINE-HEIGHT: 12pt; BORDER-RIGHT-STYLE: none; BACKGROUND-COLOR: #f4f4f4; MARGIN: 0em; PADDING-LEFT: 0px; WIDTH: 100%; PADDING-RIGHT: 0px; FONT-FAMILY: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"><SPAN style="COLOR: #606060" id=lnum30>  30:</SPAN>                 Info_TextBox.Text = ArgsX.UserState <SPAN style="COLOR: #0000ff">as</SPAN> String;</PRE><!--CRLF--><PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; PADDING-BOTTOM: 0px; LINE-HEIGHT: 12pt; BORDER-RIGHT-STYLE: none; BACKGROUND-COLOR: white; MARGIN: 0em; PADDING-LEFT: 0px; WIDTH: 100%; PADDING-RIGHT: 0px; FONT-FAMILY: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"><SPAN style="COLOR: #606060" id=lnum31>  31:</SPAN>             }</PRE><!--CRLF--><PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; PADDING-BOTTOM: 0px; LINE-HEIGHT: 12pt; BORDER-RIGHT-STYLE: none; BACKGROUND-COLOR: #f4f4f4; MARGIN: 0em; PADDING-LEFT: 0px; WIDTH: 100%; PADDING-RIGHT: 0px; FONT-FAMILY: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"><SPAN style="COLOR: #606060" id=lnum32>  32:</SPAN>             <SPAN style="COLOR: #0000ff">else</SPAN> {</PRE><!--CRLF--><PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; PADDING-BOTTOM: 0px; LINE-HEIGHT: 12pt; BORDER-RIGHT-STYLE: none; BACKGROUND-COLOR: white; MARGIN: 0em; PADDING-LEFT: 0px; WIDTH: 100%; PADDING-RIGHT: 0px; FONT-FAMILY: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"><SPAN style="COLOR: #606060" id=lnum33>  33:</SPAN>                 OpenProgress_ProgressBar.Value = ArgsX.ProgressPercentage;</PRE><!--CRLF--><PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; PADDING-BOTTOM: 0px; LINE-HEIGHT: 12pt; BORDER-RIGHT-STYLE: none; BACKGROUND-COLOR: #f4f4f4; MARGIN: 0em; PADDING-LEFT: 0px; WIDTH: 100%; PADDING-RIGHT: 0px; FONT-FAMILY: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"><SPAN style="COLOR: #606060" id=lnum34>  34:</SPAN>             }</PRE><!--CRLF--><PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; PADDING-BOTTOM: 0px; LINE-HEIGHT: 12pt; BORDER-RIGHT-STYLE: none; BACKGROUND-COLOR: white; MARGIN: 0em; PADDING-LEFT: 0px; WIDTH: 100%; PADDING-RIGHT: 0px; FONT-FAMILY: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"><SPAN style="COLOR: #606060" id=lnum35>  35:</SPAN>         };</PRE><!--CRLF--><PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; PADDING-BOTTOM: 0px; LINE-HEIGHT: 12pt; BORDER-RIGHT-STYLE: none; BACKGROUND-COLOR: #f4f4f4; MARGIN: 0em; PADDING-LEFT: 0px; WIDTH: 100%; PADDING-RIGHT: 0px; FONT-FAMILY: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"><SPAN style="COLOR: #606060" id=lnum36>  36:</SPAN>&nbsp; </PRE><!--CRLF--><PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; PADDING-BOTTOM: 0px; LINE-HEIGHT: 12pt; BORDER-RIGHT-STYLE: none; BACKGROUND-COLOR: white; MARGIN: 0em; PADDING-LEFT: 0px; WIDTH: 100%; PADDING-RIGHT: 0px; FONT-FAMILY: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"><SPAN style="COLOR: #606060" id=lnum37>  37:</SPAN>         <SPAN style="COLOR: #008000">//---- Do this when the background worker is completed </SPAN></PRE><!--CRLF--><PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; PADDING-BOTTOM: 0px; LINE-HEIGHT: 12pt; BORDER-RIGHT-STYLE: none; BACKGROUND-COLOR: #f4f4f4; MARGIN: 0em; PADDING-LEFT: 0px; WIDTH: 100%; PADDING-RIGHT: 0px; FONT-FAMILY: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"><SPAN style="COLOR: #606060" id=lnum38>  38:</SPAN>         TheLoader.RunWorkerCompleted += ( SenderX, ArgsX ) =&gt; {</PRE><!--CRLF--><PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; PADDING-BOTTOM: 0px; LINE-HEIGHT: 12pt; BORDER-RIGHT-STYLE: none; BACKGROUND-COLOR: white; MARGIN: 0em; PADDING-LEFT: 0px; WIDTH: 100%; PADDING-RIGHT: 0px; FONT-FAMILY: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"><SPAN style="COLOR: #606060" id=lnum39>  39:</SPAN>&nbsp; </PRE><!--CRLF--><PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; PADDING-BOTTOM: 0px; LINE-HEIGHT: 12pt; BORDER-RIGHT-STYLE: none; BACKGROUND-COLOR: #f4f4f4; MARGIN: 0em; PADDING-LEFT: 0px; WIDTH: 100%; PADDING-RIGHT: 0px; FONT-FAMILY: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"><SPAN style="COLOR: #606060" id=lnum40>  40:</SPAN>             RunWorkerCompletedEventArgs args = ArgsX <SPAN style="COLOR: #0000ff">as</SPAN> RunWorkerCompletedEventArgs;</PRE><!--CRLF--><PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; PADDING-BOTTOM: 0px; LINE-HEIGHT: 12pt; BORDER-RIGHT-STYLE: none; BACKGROUND-COLOR: white; MARGIN: 0em; PADDING-LEFT: 0px; WIDTH: 100%; PADDING-RIGHT: 0px; FONT-FAMILY: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"><SPAN style="COLOR: #606060" id=lnum41>  41:</SPAN>&nbsp; </PRE><!--CRLF--><PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; PADDING-BOTTOM: 0px; LINE-HEIGHT: 12pt; BORDER-RIGHT-STYLE: none; BACKGROUND-COLOR: #f4f4f4; MARGIN: 0em; PADDING-LEFT: 0px; WIDTH: 100%; PADDING-RIGHT: 0px; FONT-FAMILY: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"><SPAN style="COLOR: #606060" id=lnum42>  42:</SPAN>             <SPAN style="COLOR: #0000ff">if</SPAN> ( args.Error != <SPAN style="COLOR: #0000ff">null</SPAN> ) {</PRE><!--CRLF--><PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; PADDING-BOTTOM: 0px; LINE-HEIGHT: 12pt; BORDER-RIGHT-STYLE: none; BACKGROUND-COLOR: white; MARGIN: 0em; PADDING-LEFT: 0px; WIDTH: 100%; PADDING-RIGHT: 0px; FONT-FAMILY: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"><SPAN style="COLOR: #606060" id=lnum43>  43:</SPAN>                 PopErrorDialog( args.Error, <SPAN style="COLOR: #006080">"Cannot process file!"</SPAN> );</PRE><!--CRLF--><PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; PADDING-BOTTOM: 0px; LINE-HEIGHT: 12pt; BORDER-RIGHT-STYLE: none; BACKGROUND-COLOR: #f4f4f4; MARGIN: 0em; PADDING-LEFT: 0px; WIDTH: 100%; PADDING-RIGHT: 0px; FONT-FAMILY: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"><SPAN style="COLOR: #606060" id=lnum44>  44:</SPAN>             }</PRE><!--CRLF--><PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; PADDING-BOTTOM: 0px; LINE-HEIGHT: 12pt; BORDER-RIGHT-STYLE: none; BACKGROUND-COLOR: white; MARGIN: 0em; PADDING-LEFT: 0px; WIDTH: 100%; PADDING-RIGHT: 0px; FONT-FAMILY: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"><SPAN style="COLOR: #606060" id=lnum45>  45:</SPAN>             <SPAN style="COLOR: #0000ff">else</SPAN></PRE><!--CRLF--><PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; PADDING-BOTTOM: 0px; LINE-HEIGHT: 12pt; BORDER-RIGHT-STYLE: none; BACKGROUND-COLOR: #f4f4f4; MARGIN: 0em; PADDING-LEFT: 0px; WIDTH: 100%; PADDING-RIGHT: 0px; FONT-FAMILY: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"><SPAN style="COLOR: #606060" id=lnum46>  46:</SPAN>             <SPAN style="COLOR: #0000ff">if</SPAN> ( args.Cancelled ) {</PRE><!--CRLF--><PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; PADDING-BOTTOM: 0px; LINE-HEIGHT: 12pt; BORDER-RIGHT-STYLE: none; BACKGROUND-COLOR: white; MARGIN: 0em; PADDING-LEFT: 0px; WIDTH: 100%; PADDING-RIGHT: 0px; FONT-FAMILY: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"><SPAN style="COLOR: #606060" id=lnum47>  47:</SPAN>                 Info_TextBox.Text = <SPAN style="COLOR: #006080">"Loading cancled"</SPAN>;</PRE><!--CRLF--><PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; PADDING-BOTTOM: 0px; LINE-HEIGHT: 12pt; BORDER-RIGHT-STYLE: none; BACKGROUND-COLOR: #f4f4f4; MARGIN: 0em; PADDING-LEFT: 0px; WIDTH: 100%; PADDING-RIGHT: 0px; FONT-FAMILY: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"><SPAN style="COLOR: #606060" id=lnum48>  48:</SPAN>             }</PRE><!--CRLF--><PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; PADDING-BOTTOM: 0px; LINE-HEIGHT: 12pt; BORDER-RIGHT-STYLE: none; BACKGROUND-COLOR: white; MARGIN: 0em; PADDING-LEFT: 0px; WIDTH: 100%; PADDING-RIGHT: 0px; FONT-FAMILY: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"><SPAN style="COLOR: #606060" id=lnum49>  49:</SPAN>             <SPAN style="COLOR: #0000ff">else</SPAN> {</PRE><!--CRLF--><PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; PADDING-BOTTOM: 0px; LINE-HEIGHT: 12pt; BORDER-RIGHT-STYLE: none; BACKGROUND-COLOR: #f4f4f4; MARGIN: 0em; PADDING-LEFT: 0px; WIDTH: 100%; PADDING-RIGHT: 0px; FONT-FAMILY: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"><SPAN style="COLOR: #606060" id=lnum50>  50:</SPAN>                 Info_TextBox.Text = <SPAN style="COLOR: #006080">"File Loaded"</SPAN>;</PRE><!--CRLF--><PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; PADDING-BOTTOM: 0px; LINE-HEIGHT: 12pt; BORDER-RIGHT-STYLE: none; BACKGROUND-COLOR: white; MARGIN: 0em; PADDING-LEFT: 0px; WIDTH: 100%; PADDING-RIGHT: 0px; FONT-FAMILY: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"><SPAN style="COLOR: #606060" id=lnum51>  51:</SPAN>             }</PRE><!--CRLF--><PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; PADDING-BOTTOM: 0px; LINE-HEIGHT: 12pt; BORDER-RIGHT-STYLE: none; BACKGROUND-COLOR: #f4f4f4; MARGIN: 0em; PADDING-LEFT: 0px; WIDTH: 100%; PADDING-RIGHT: 0px; FONT-FAMILY: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"><SPAN style="COLOR: #606060" id=lnum52>  52:</SPAN>&nbsp; </PRE><!--CRLF--><PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; PADDING-BOTTOM: 0px; LINE-HEIGHT: 12pt; BORDER-RIGHT-STYLE: none; BACKGROUND-COLOR: white; MARGIN: 0em; PADDING-LEFT: 0px; WIDTH: 100%; PADDING-RIGHT: 0px; FONT-FAMILY: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"><SPAN style="COLOR: #606060" id=lnum53>  53:</SPAN>             Cancel_Button.IsEnabled = <SPAN style="COLOR: #0000ff">false</SPAN>;</PRE><!--CRLF--><PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; PADDING-BOTTOM: 0px; LINE-HEIGHT: 12pt; BORDER-RIGHT-STYLE: none; BACKGROUND-COLOR: #f4f4f4; MARGIN: 0em; PADDING-LEFT: 0px; WIDTH: 100%; PADDING-RIGHT: 0px; FONT-FAMILY: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"><SPAN style="COLOR: #606060" id=lnum54>  54:</SPAN>             Cancel_Button.Click -= TheLoader.PerformCancel;</PRE><!--CRLF--><PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; PADDING-BOTTOM: 0px; LINE-HEIGHT: 12pt; BORDER-RIGHT-STYLE: none; BACKGROUND-COLOR: white; MARGIN: 0em; PADDING-LEFT: 0px; WIDTH: 100%; PADDING-RIGHT: 0px; FONT-FAMILY: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"><SPAN style="COLOR: #606060" id=lnum55>  55:</SPAN>             OpenProgress_ProgressBar.IsEnabled = <SPAN style="COLOR: #0000ff">false</SPAN>;</PRE><!--CRLF--><PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; PADDING-BOTTOM: 0px; LINE-HEIGHT: 12pt; BORDER-RIGHT-STYLE: none; BACKGROUND-COLOR: #f4f4f4; MARGIN: 0em; PADDING-LEFT: 0px; WIDTH: 100%; PADDING-RIGHT: 0px; FONT-FAMILY: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"><SPAN style="COLOR: #606060" id=lnum56>  56:</SPAN>             OpenProgress_ProgressBar.Visibility = Visibility.Hidden;</PRE><!--CRLF--><PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; PADDING-BOTTOM: 0px; LINE-HEIGHT: 12pt; BORDER-RIGHT-STYLE: none; BACKGROUND-COLOR: white; MARGIN: 0em; PADDING-LEFT: 0px; WIDTH: 100%; PADDING-RIGHT: 0px; FONT-FAMILY: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"><SPAN style="COLOR: #606060" id=lnum57>  57:</SPAN>             OpenAFile_Button.IsEnabled = <SPAN style="COLOR: #0000ff">true</SPAN>;</PRE><!--CRLF--><PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; PADDING-BOTTOM: 0px; LINE-HEIGHT: 12pt; BORDER-RIGHT-STYLE: none; BACKGROUND-COLOR: #f4f4f4; MARGIN: 0em; PADDING-LEFT: 0px; WIDTH: 100%; PADDING-RIGHT: 0px; FONT-FAMILY: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"><SPAN style="COLOR: #606060" id=lnum58>  58:</SPAN>         };</PRE><!--CRLF--><PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; PADDING-BOTTOM: 0px; LINE-HEIGHT: 12pt; BORDER-RIGHT-STYLE: none; BACKGROUND-COLOR: white; MARGIN: 0em; PADDING-LEFT: 0px; WIDTH: 100%; PADDING-RIGHT: 0px; FONT-FAMILY: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"><SPAN style="COLOR: #606060" id=lnum59>  59:</SPAN>&nbsp; </PRE><!--CRLF--><PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; PADDING-BOTTOM: 0px; LINE-HEIGHT: 12pt; BORDER-RIGHT-STYLE: none; BACKGROUND-COLOR: #f4f4f4; MARGIN: 0em; PADDING-LEFT: 0px; WIDTH: 100%; PADDING-RIGHT: 0px; FONT-FAMILY: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"><SPAN style="COLOR: #606060" id=lnum60>  60:</SPAN>         <SPAN style="COLOR: #008000">//---- Start the ascynrnous file loading operation</SPAN></PRE><!--CRLF--><PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; PADDING-BOTTOM: 0px; LINE-HEIGHT: 12pt; BORDER-RIGHT-STYLE: none; BACKGROUND-COLOR: white; MARGIN: 0em; PADDING-LEFT: 0px; WIDTH: 100%; PADDING-RIGHT: 0px; FONT-FAMILY: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"><SPAN style="COLOR: #606060" id=lnum61>  61:</SPAN>         TheLoader.RunWorkerAsync( ofd.FileName );</PRE><!--CRLF--><PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; PADDING-BOTTOM: 0px; LINE-HEIGHT: 12pt; BORDER-RIGHT-STYLE: none; BACKGROUND-COLOR: #f4f4f4; MARGIN: 0em; PADDING-LEFT: 0px; WIDTH: 100%; PADDING-RIGHT: 0px; FONT-FAMILY: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"><SPAN style="COLOR: #606060" id=lnum62>  62:</SPAN>     }</PRE><!--CRLF--><PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; PADDING-BOTTOM: 0px; LINE-HEIGHT: 12pt; BORDER-RIGHT-STYLE: none; BACKGROUND-COLOR: white; MARGIN: 0em; PADDING-LEFT: 0px; WIDTH: 100%; PADDING-RIGHT: 0px; FONT-FAMILY: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"><SPAN style="COLOR: #606060" id=lnum63>  63:</SPAN>     <SPAN style="COLOR: #0000ff">catch</SPAN> ( Exception Ex ) {</PRE><!--CRLF--><PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; PADDING-BOTTOM: 0px; LINE-HEIGHT: 12pt; BORDER-RIGHT-STYLE: none; BACKGROUND-COLOR: #f4f4f4; MARGIN: 0em; PADDING-LEFT: 0px; WIDTH: 100%; PADDING-RIGHT: 0px; FONT-FAMILY: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"><SPAN style="COLOR: #606060" id=lnum64>  64:</SPAN>         PopErrorDialog( Ex, <SPAN style="COLOR: #006080">"General Failure!"</SPAN> );</PRE><!--CRLF--><PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; PADDING-BOTTOM: 0px; LINE-HEIGHT: 12pt; BORDER-RIGHT-STYLE: none; BACKGROUND-COLOR: white; MARGIN: 0em; PADDING-LEFT: 0px; WIDTH: 100%; PADDING-RIGHT: 0px; FONT-FAMILY: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"><SPAN style="COLOR: #606060" id=lnum65>  65:</SPAN>     }</PRE><!--CRLF--><PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; PADDING-BOTTOM: 0px; LINE-HEIGHT: 12pt; BORDER-RIGHT-STYLE: none; BACKGROUND-COLOR: #f4f4f4; MARGIN: 0em; PADDING-LEFT: 0px; WIDTH: 100%; PADDING-RIGHT: 0px; FONT-FAMILY: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"><SPAN style="COLOR: #606060" id=lnum66>  66:</SPAN> }</PRE><!--CRLF--></DIV></DIV>
<DIV>Functional programming is key to making this code clean and straight forward.&nbsp;&nbsp; Here we’re using lambda functions connected to the AsyncFileLoader’s progress and completion events.</DIV>
<P>You can see in the progress changed handler how no state needs to be kept – this lambda function gets all the data it needs from the event.&nbsp;&nbsp; You can see how the sentinel value (int.MinValue) is used to trigger the change in UI state.</P>
<P>Completion is handles in a similarly manner and resets the UI state.&nbsp;&nbsp; This lambda also handles any errors thrown by the loader by checking the args.Error member which will reference an exception if one was thrown.</P>
<P>This is a great example of using multi-threaded programming for something other than speeding up a computationally bound algorithm using parallelization.&nbsp;&nbsp; Some may suggest that this isn’t “real multi-core” programming, but it is.&nbsp; Indeed, the developer doesn’t need to know how to implement complex inter thread communication or synchronization, but just because this isn’t hard, doesn’t mean it isn’t real multi-threaded, and multi-core enabled code.&nbsp; It absolutely is and the developer does need to understand asynchronous programming techniques to use it. </P>
<P>Using the BackgroundWorker class is a very simple straight forward way to enable your programs to be more responsive, and to leverage multi-threaded and multi-core performance.&nbsp;&nbsp; You can use other managed code techniques such as threads and dispatching for more sophisticated work.&nbsp;&nbsp; </P>
<DIV style="PADDING-BOTTOM: 0px; MARGIN: 0px; PADDING-LEFT: 0px; PADDING-RIGHT: 0px; DISPLAY: inline; FLOAT: none; PADDING-TOP: 0px" id=scid:0767317B-992E-4b12-91E0-4F059A8CECA8:ef56a28c-723b-4ae1-8908-a387f076f35d class=wlWriterEditableSmartContent>del.icio.us Tags: <A href="http://del.icio.us/popular/performacne" rel=tag mce_href="http://del.icio.us/popular/performacne">performacne</A>,<A href="http://del.icio.us/popular/programming" rel=tag mce_href="http://del.icio.us/popular/programming">programming</A>,<A href="http://del.icio.us/popular/C%23" rel=tag mce_href="http://del.icio.us/popular/C%23">C#</A>,<A href="http://del.icio.us/popular/multi-core" rel=tag mce_href="http://del.icio.us/popular/multi-core">multi-core</A>,<A href="http://del.icio.us/popular/multicore" rel=tag mce_href="http://del.icio.us/popular/multicore">multicore</A></DIV>
<P>You can find the complete VS 2008 project in the attached ZIP file.</P>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Components.PostAttachments/00/09/85/94/13/BackgroundFileOpenExample.zip" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-components-postattachments/00-09-85-94-13/BackgroundFileOpenExample.zip">BackgroundFileOpenExample.zip</a></p>]]></content:encoded>
    </item>
    <item>
      <title>StackOverflow answer – why learn multi-core programming?</title>
      <link>https://docs.microsoft.com/archive/blogs/pigscanfly/stackoverflow-answer-why-learn-multi-core-programming</link>
      <pubDate>Sun, 29 Mar 2009 20:39:09 GMT</pubDate>
      <dc:creator><![CDATA[rgr]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/pigscanfly/2009/03/29/stackoverflow-answer-why-learn-multi-core-programming/</guid>
      <description><![CDATA[I must admit, I’m addicted to Stackoverflow.&#160; Its a great site, being both interesting and easy...]]></description>
      <content:encoded><![CDATA[<p>I must admit, I’m addicted to <a href="http://stackoverflow.com">Stackoverflow</a>.&#160; Its a great site, being both interesting and easy to use.</p>  <p>Recently, I ran across this question “<a href="http://stackoverflow.com/questions/543755/are-you-concerned-about-multicore">Are you concerned about multicore</a>”.&#160;&#160; <a href="http://stackoverflow.com/users/2827/henryr">HenryR</a>, a PhD candidate at Cambridge is asking if the “developer on the street” needs to concern him/herself with multi-core development&#160; practices.&#160;&#160; </p>  <p>Henry’s question has a few answers, including the accepted one <a href="http://stackoverflow.com/users/2509/dmckee">dmckee</a> (a particle physicist)which I’ll focus on here. </p>  <p>There are <em>many</em> types of programs such as</p>  <ul>   <li>A simple script one of might write to do some work then throw away, </li>    <li>high performance very parallel scientific&#160; applications, </li>    <li>Main stream operating systems </li>    <li>Line of business applications </li>    <li>Web based apps </li>    <li>Command line based applications </li>    <li>Applications with graphical user interfaces. </li> </ul>  <p>This is simply the tip of the ice berg – I’m confident that with a little brainstorming, this list would be come large. </p>  <p>Dmckee’s answer is correct – but only for a small set of things.&#160; Indeed, for a very simple application, that is not CPU bound, then making it multi-threaded may be more work than needed.&#160; For example, I have utilities that are not multi-threaded.</p>  <p>However, even utilities can take advantage of multi-threading, and I argue that its de rigueur for a production program to do so. </p>  <p>The astute reader may say “<em>But wait a minute!&#160;&#160; Henry ask about multi-core, not multi-threading…</em>”.</p>  <p>Yup, but to leverage multi-core, you need to write multi-threaded programs.&#160;&#160; Using more than one thread has other advantages beyond parallelizing CPU bound operations so they have better throughput. </p>  <p>To pre-fetch the next comment “But if its not CPU bound, then why bother with multi-threading?&#160; That’s just a waste of time!”</p>  <p>In my mind, there are three reasons for this:</p>  <ol>   <li>It can make your program more responsive from a user perspective. </li>    <li>Even for things that are not CPU bound, it makes sense to do them in parallel. </li>    <li>It can break up complex single threaded state machines into simpler, more procedural code. </li> </ol>  <p>In Windows, the user interface is message based: Windows sends a UI program a message for ech UI event the program needs to handle.&#160;&#160; A program with any kind of graphical UI uses the <a href="http://msdn.microsoft.com/en-us/library/ms632590(VS.85).aspx" target="_blank">GetNextMessage() family of functions</a> to get them.&#160; I don’t know about Linux or OSX, but I suspect they are similar in this regard.</p>  <p>This is conventionally done in a <a href="http://msdn.microsoft.com/en-us/library/ms644928.aspx" target="_blank">message loop</a> where a program loops on getting then processing messages.&#160;&#160; If there are no messages, then the program can wait (block) for a new message, or do some background, or idle processing.</p>  <p>Messages included all kinds of things, but most importantly user input – mouse moves and clicks, and keyboard events.&#160; These are often translated into windowing operations (moves, resizes, etc) and control actions (button clicks, scrolling, etc).&#160; In short, this means that coding handling the UI is a big state machine and that this state is not kept on the stack.&#160; It has to be kept explicitly somewhere else.&#160;&#160;&#160; </p>  <p>This has an important implication – for an application to main responsive, it must be able to quickly and consistently service the message loop.&#160;&#160; This is done on a single thread, indeed many applications only have a single thread that does everything.&#160; </p>  <p>Windows programs have been written this way for a long time.&#160; Some people might argue that this is a design deficiency.&#160; That’s a topic for a different discussion about application compatibility – do remember, this pattern was set back in the very early 90’s – Windows 3.11 was released in 1992.</p>  <p>In any case, delays in the message loop that the user can perceive are called hangs.&#160; There are two ways to keep the message loop from hanging.</p>  <ol>   <li>Break up all operations into pieces that execute quickly enough so that the message loop can always be serviced quickly.&#160;&#160; Indeed, lots of developers have tackled the problem just this way.      <br /></li>    <li>Move longer running operations to another thread, or threads. </li> </ol>  <p>The short story is that only #2 works effectively. Why?&#160; Simply put – I/O.&#160; Specifically disk and network I/O.&#160; But other I/O, such as GPU operations can also be an issue. </p>  <p>The problem is that any disk or network I/O operation can potentially be long – hundreds or thousands of milliseconds long.&#160; Programs that do their file I/O and networking I/O on the UI thread will have hangs.&#160; It is unavoidable.</p>  <p>Some may point out that “Hey!&#160; That doesn’t matter, making it multi-threaded doesn’t speed things up!”.</p>  <p>Right…. and wrong…</p>  <p>Right in the sense that it doesn’t increase an applications throughput – the work still has to get done.&#160;&#160; But wrong in the sense that it absolutely positively benefits the user. </p>  <p>So for point <strong>#1 multi-threading can make your program more responsive from a user perspective </strong>because you can move potentially long running operations off the UI thread – keeping the UI “alive” and responsive.&#160;&#160; Trust me, your users will love you for this. </p>  <p>In my next post, I”ll discusses the source code for a C# program that shows how simple it is to move operations off the UI thread in WPF applications.&#160;&#160; This doesn’t require any complex knowledge of fine grained synchronization, or complex multi-threaded programming.&#160; The code is also easy to understand, not state machine driven and easy to debug.&#160;&#160; All things that conventional wisdom holds is true for multi-threaded programming.</p>  <p>In future posts, I’ll talk more about the example source above, points #2 and #3 , and some general multi-core and multi-threaded topics. </p>  <p>In summary – multi-core and multi-threaded programming is much more than simply speeding up (parallelizing) compute bound operations.&#160; Efficient threading can bring other benefits to your programs as well.&#160; </p>  <div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:6d5f15af-9c70-4831-a42a-f4e0d1814695" class="wlWriterEditableSmartContent">del.icio.us Tags: <a href="http://del.icio.us/popular/performacne+programming+C%23+multi-core+multicore" rel="tag">performacne programming C# multi-core multicore</a></div>]]></content:encoded>
    </item>
    <item>
      <title>So just what is in a trace? Using the xperf trace dumper</title>
      <link>https://docs.microsoft.com/archive/blogs/pigscanfly/so-just-what-is-in-a-trace-using-the-xperf-trace-dumper</link>
      <pubDate>Sun, 16 Mar 2008 12:04:10 GMT</pubDate>
      <dc:creator><![CDATA[rgr]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/pigscanfly/2008/03/16/so-just-what-is-in-a-trace-using-the-xperf-trace-dumper/</guid>
      <description><![CDATA[There is a lot of information in a typical kernel trace.&#160; While the Performance Analyzer tool...]]></description>
      <content:encoded><![CDATA[<p>There is a lot of information in a typical kernel trace.&#160; While the Performance Analyzer tool is quite powerful and makes it easy to view a trace graphically, sometimes you just need to see what is in the trace directly.&#160; Xperf makes this easy.</p>  <p>First, its important to understand that a trace file (.ETL) is simply just the buffers produced by trace session written to a file.&#160; The data in an ETL file isn't pre-processed, summarized, or otherwise annotated with meta data as it comes out of the OS.&#160; Its is just the raw data that comes from a ETW session.&#160; This is because ETW is designed for log time efficiency - ETW does the absolutely minimal amount of work needed to get the trace data to a file, or other consumer. </p>  <p>This means that all the heavy lifting of post processing trace data happens later. With the xperf tools, there are two places where this occurs:</p>  <ol>   <li>In the merge step, xperf takes the kernel trace and trace files and merges them into a single trace file.&#160; Xperf will merges (adds) meta data to the trace (I've got another post that provides all the detailed on merging in the works...).&#160; The result of merging is a single trace file that can be analyzed by the tools directly on the target machine, or copied to another system for analysis.&#160;&#160; Note that the merge step <u>must</u> happen on the system where the trace was taken (the target system).       <br /></li>    <li>When a trace is processed xperf using actions, or loaded into Performance Analyzer, the core trace processing components do a lot of work on the raw trace data.&#160; This includes things like mapping process IDs (PIDs) to file and process names, mapping addresses to filenames, loading symbols for address, unifying stacks, and handling 64-bit and 32-bit differences. </li> </ol>  <p>As you've seen in the <a href="http://blogs.msdn.com/pigscanfly/pages/xperf-articles.aspx" target="_blank">other posts</a>, once a trace is merged it can be viewed in the Performance Analyzer.&#160; But, xperf also allows you to see what is in the trace using the dumper action.&#160; This is easy to do:</p>  <blockquote>   <p><font face="Courier New"><strong>xperf -i fs.etl -a dmper &gt;fs.csv</strong></font></p> </blockquote>  <p>The <strong><font face="Courier New">-i fs.etl</font></strong> specified that the input file is FS.ETL.&#160;&#160;&#160; The <font face="Courier New"><strong>-a dumper</strong></font> parameter tells xperf to execute the dumper action.&#160;&#160; The output goes to the standard output.</p>  <p>There is a short cut for this as well: the dumper action is the default action so if you only specify an input file then xperf simply dumps it.&#160;&#160; For example, the following command does the same thing as the one above:</p>  <blockquote>   <p><font face="Courier New"><strong>xperf -i fs.etl&#160; &gt;fs.csv</strong></font></p> </blockquote>  <p>The resulting file is an ANSI text file where each line is one record.&#160;&#160; Each record consists of a comma delimited set of fields.&#160; The first field of each line is the name (or type) of the record.&#160; </p>  <p>There are some special lines and sections at the front of the file.&#160;&#160; Each record type is described by a header line.&#160;&#160; The header lines are delimited by the <strong>'BeginHeader'</strong> and <strong>'EndHeader'</strong> lines.&#160;&#160; Note that the line immediately after the 'EndHeader' line is unique, it doesn't have a header line.&#160; This line describes some of the characteristics of the trace such as its duration, and the pointer size.</p>  <p>The first field of each header line is the name (or type) of the ETW record that the header line describes.&#160; The rest of the fields are the names of each of the fields for the record type.&#160; Here is an example of the process start event header (P-Start) and a P-Start event. </p>  <blockquote>   <p><font face="Courier New">P-Start,&#160; TimeStamp, Process Name ( PID),&#160; ParentPID,&#160; SessionID,&#160; UniqueKey, UserSid, Command Line</font></p>    <p><font face="Courier New">P-Start, 1017280, fs.exe (3004), 3608, 1, 0x86661508,        <br />S-1-5-21-626881126-397955417-188441333-3225678, c:\coding\fs\Release\fs\fs.exe&#160; blflargorg c:\coding\*.cpp *.h -s</font> </p> </blockquote>  <p>This event describes the start of a process.&#160; There is also a corresponding P-End event. For processes that are already running when he trace is begun, the kernel logger includes a pseudo P-Start event.&#160; </p>  <p>This means that every PID seen in other events will have a corresponding P-Start event in the trace before it is seen in an event. </p>  <p>Also note that xperf will dump events that you add to your own applications so long as you include an <a href="http://msdn2.microsoft.com/en-us/library/aa384043(VS.85).aspx" target="_blank">event manifest</a> in your app.&#160; So, you can add your own events and use xperf to dump them in the context of all the other events you include in the trace. </p>  <div class="wlWriterSmartContent" id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:14307c8f-2b25-40e1-bae1-3e6d6a7fb480" style="padding-right: 0px; display: inline; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px">del.icio.us Tags: <a href="http://del.icio.us/popular/performance" rel="tag">performance</a>,<a href="http://del.icio.us/popular/xperf" rel="tag">xperf</a>,<a href="http://del.icio.us/popular/windows" rel="tag">windows</a></div>]]></content:encoded>
    </item>
    <item>
      <title>XPerf Articles</title>
      <link>https://docs.microsoft.com/archive/blogs/pigscanfly/xperf-articles</link>
      <pubDate>Sat, 15 Mar 2008 13:24:00 GMT</pubDate>
      <dc:creator><![CDATA[rgr]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/pigscanfly/2008/03/15/xperf-articles/</guid>
      <description><![CDATA[Here is a chronological list of the my posts about the xperf tools.&nbsp; If you are new to the...]]></description>
      <content:encoded><![CDATA[
<p>Here is a chronological list of the my posts about the xperf tools.&nbsp; If you are new to the tools, or simply want to find a specific article, this is a good place to start.&nbsp; I've listed each article's title and first paragraph.&nbsp;&nbsp; The title is the link to the post.&nbsp; </p>

<p><a href="http://blogs.msdn.com/pigscanfly/archive/2008/02/09/xperf-a-new-tool-in-the-windows-sdk.aspx" mce_href="http://blogs.msdn.com/pigscanfly/archive/2008/02/09/xperf-a-new-tool-in-the-windows-sdk.aspx"><b><font size="4">Xperf, a new tool in the Windows SDK</font></b></a> <br>The SDK team just shipped the latest version of the Windows SDK which supports Windows Server 2008 and Vista SP1.&nbsp; The SDK now includes an important new tool; the <b>Windows Performance Tool Kit</b> from the Windows performance team (we call them the xperf tools for short...)</p>

<p><a href="http://blogs.msdn.com/pigscanfly/archive/2008/02/11/xperf-tools-landing-page-and-update.aspx" mce_href="http://blogs.msdn.com/pigscanfly/archive/2008/02/11/xperf-tools-landing-page-and-update.aspx"><b><font size="4">Xperf Tools Landing Page and Update</font></b></a> <br>The WHDC folks now have web page setup for the Windows Performance Toolkit (aka the 'xperf tools').&nbsp; The page includes downloads for updates to the versions that ship in the SDK.&nbsp; In the near future, this page will include pointers to updated documentation, and discussion forums.</p>

<p><a href="http://blogs.msdn.com/pigscanfly/archive/2008/02/16/using-xperf-to-take-a-trace.aspx" mce_href="http://blogs.msdn.com/pigscanfly/archive/2008/02/16/using-xperf-to-take-a-trace.aspx"><font size="4"><b>Using Xperf to take a Trace (updated)</b></font></a> <br>Lets get to it!&nbsp; Here is how to take a basic trace then look at CPU and disk utilization.&nbsp;&nbsp;&nbsp; Its really simple, just three commands to turn on tracing, turn it off, and then view the trace. </p>

<p><a href="http://blogs.msdn.com/pigscanfly/archive/2008/02/24/xperf-support-for-xp.aspx" mce_href="http://blogs.msdn.com/pigscanfly/archive/2008/02/24/xperf-support-for-xp.aspx"><b><font size="4">Xperf support for XP</font></b></a> <br>"Do the xperf tools support XP or Windows Server 2003?" is a frequently ask question.&nbsp; The answer is no mostly, and yes for a few things. </p>

<p><a href="http://blogs.msdn.com/pigscanfly/archive/2008/03/02/using-the-windows-sample-profiler-with-xperf.aspx" mce_href="http://blogs.msdn.com/pigscanfly/archive/2008/03/02/using-the-windows-sample-profiler-with-xperf.aspx"><b><font size="4">Using the Windows Sample Profiler with Xperf</font></b></a> <br>Using the xperf tools, ETW, and the kernel sample profile interrupt all together provides a very effective and easy to use sample profiler for the analysis of both application and system wide performance.&nbsp; At each sample interrupt, the ETW sub-system captures the instruction pointer and the stack.&nbsp; This data is lazily and efficiently logged to an ETL file.&nbsp; Once the data is saved, it can be analyzed with Performance Analyzer.</p>

<p><a href="http://blogs.msdn.com/pigscanfly/archive/2008/03/16/so-just-what-is-in-a-trace-using-the-xperf-trace-dumper.aspx" mce_href="http://blogs.msdn.com/pigscanfly/archive/2008/03/16/so-just-what-is-in-a-trace-using-the-xperf-trace-dumper.aspx"><b><font size="4">So just what is in a trace? Using the xperf trace dumper</font></b></a> <br>There is a lot of information in a typical kernel trace.&nbsp; While the Performance Analyzer tool is quite powerful and makes it easy to view a trace graphically, sometimes you just need to see what is in the trace directly.&nbsp; Xperf makes this easy.</p>

<p><a href="http://blogs.msdn.com/pigscanfly/archive/2009/08/06/stack-walking-in-xperf.aspx" title="Stack walking with xperf" target="_blank" mce_href="http://blogs.msdn.com/pigscanfly/archive/2009/08/06/stack-walking-in-xperf.aspx"><b><font size="4">Stack Walking with Xperf</font></b></a><br>
Bruce Dawson is a performance analyst on the client performance team.&nbsp; He has written this guest post on enabling stack walking using xperf for both 32-bit and 64-bit Windows systems (Vista and Win7).</p>
]]></content:encoded>
    </item>
    <item>
      <title>Using the Windows Sample Profiler with Xperf</title>
      <link>https://docs.microsoft.com/archive/blogs/pigscanfly/using-the-windows-sample-profiler-with-xperf</link>
      <pubDate>Sun, 02 Mar 2008 12:06:12 GMT</pubDate>
      <dc:creator><![CDATA[rgr]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/pigscanfly/2008/03/02/using-the-windows-sample-profiler-with-xperf/</guid>
      <description><![CDATA[Using the xperf tools, ETW, and the kernel sample profile interrupt all together provides a very...]]></description>
      <content:encoded><![CDATA[<p>Using the xperf tools, ETW, and the kernel sample profile interrupt all together provides a very effective and easy to use sample profiler for the analysis of both application and system wide performance.&#160; At each sample interrupt, the ETW sub-system captures the instruction pointer and the stack.&#160; This data is lazily and efficiently logged to an ETL file.&#160; Once the data is saved, it can be analyzed with Performance Analyzer.</p>  <p align="center"><em>The next article in this series is&#160; </em><a href="http://blogs.msdn.com/pigscanfly/archive/2008/03/16/so-just-what-is-in-a-trace-using-the-xperf-trace-dumper.aspx">So just what is in a trace? Using the xperf trace dumper</a></p>  <p align="center"><em><u>Note:</u></em> <em>the examples in this post only works on Vista or Server 2008 32-bit;&#160; Prior operating system's do not support taking stack traces.&#160; Taking stack traces on 64-bit platforms will be the topic of another post.</em></p>  <p>Here is an example of profiling FS.EXE, a grep-like utility I've written.&#160; I use this tool for experimenting with various topics such as efficient I/O, well performing string matching algorithms, and instrumenting applications with ETW. </p>  <p>For this test, I put the following commands in a CMD file: </p>  <ul>   <ul>     <li><font face="Courier New" size="2">xperf -on PROC_THREAD+LOADER+INTERRUPT+DPC+PROFILE          <br />-stackwalk profile           <br />-minbuffers 16 -maxbuffers 1024 -flushtimer 0           <br />-f e:\tmp.etl           <br /></font></li>      <li><font face="Courier New" size="2">fs.exe farglenorgin c:\coding\*.cpp *.h -s          <br /></font></li>      <li><font face="Courier New" size="2">xperf -d profile.etl</font> </li>   </ul> </ul>  <p>Since the commands are a bit long, I've separated them above and added line breaks to make them readable.&#160; Each command above should be on one line in your command file.</p>  <p>The first command turns on the kernel logger and enables the following events:</p>  <ul>   <li>PROC_THREAD flag enables the <a href="http://msdn2.microsoft.com/en-us/library/aa364092(VS.85).aspx" target="_blank">process</a> and <a href="http://msdn2.microsoft.com/en-us/library/aa364132(VS.85).aspx" target="_blank">thread</a> events. These mark the beginning and ending of each process and thread.&#160; The kernel provider guarantees that there will be a begin/end pair for every process and thread during the trace.&#160;&#160; Process and threads that exist before the trace was started or are still running when the trace is stopped also have these events. </li>    <li>The LOADER flag enables the <a href="http://msdn2.microsoft.com/en-us/library/aa364068(VS.85).aspx" target="_blank">loader events</a> that log when the kernel loads an image (an EXE or DLL) </li>    <li>The INTERRUPT&#160; and DPC flags enable the ETW <a href="http://msdn2.microsoft.com/en-us/library/aa964780(VS.85).aspx" target="_blank">interrupt</a> and <a href="http://msdn2.microsoft.com/en-us/library/aa964748(VS.85).aspx" target="_blank">DPC</a> events which mark each interrupt and deferred procedure call which are routines that run at <a href="DISPATCH_LEVEL" target="_blank">DISPATCH_LEVEL</a>t </li>    <li>The PROFILE flag does two things; it turns on the systems sample profile interrupt and it enables the kernel's <a href="http://msdn2.microsoft.com/en-us/library/aa964806(VS.85).aspx" target="_blank">sample profile ETW event</a>. </li> </ul>  <p>The other flags are important as well.</p>  <ul>   <li>The <strong>-stackwalk profile</strong> parameter turns on ETW's stack walking feature for the sample profile event.&#160;&#160; Every time a sample profile event is triggered by the sample profile interrupt, ETW will capture the stack and save the data in the trace buffers.&#160;&#160; </li>    <li>The <strong>-minbuffers 16</strong> parameter sets the minimum number of buffers that ETW will allocate for storing events.&#160; Note, you need at least two for each processor in you system. </li>    <li>The <strong>-maxbuffers 1024</strong> parameter sets the maximum number of buffers ETW will allocate to 1024 - a total of 64MB. </li>    <li>The <strong>-flushtimer 0</strong> parameter tells ETW to never flush the buffers based on&#160; timer, buffer's will only be written to disk when they are full. </li>    <li>The <strong>-f e:\tmp.etl</strong> parameter tells ETW to lazily write the full ETW buffers to e:\tmp.etl.&#160;&#160; This puts the log file on a different physical drive than the drive on which the experiment is running.&#160; This means that the writes that ETW uses to save the trace data do not occur on the interesting drive. </li> </ul>  <p>The second command simply runs the experiment.&#160; It searches for the string '<font face="Courier New">farglenorgin</font>' in all my .CPP and .H files.&#160; I'm using a string that doesn't exist so I execute the worst case code paths in the application.&#160; Replace this command with a command to run your experiment, or a pause instruction so you can dork around with a graphical program. </p>  <p>The third command simply stops the kernel logger, merges the data and saves it in <strong>profile.etl</strong>. </p>  <blockquote>   <p><em><strong><font color="#ff8000">NOTE: </font></strong>These commands need to be run from an elevated command prompt.&#160;&#160; Controlling ETW tracing requires administrative privileges.</em> </p> </blockquote>  <p>There is now one other thing to do before examining the data - setting the symbol path.&#160;&#160; Here is how I set the symbol path for this example:&#160; </p>  <blockquote>   <p><font face="Courier New">set _NT_SYMBOL_PATH =        <br /></font><font face="Courier New" size="2">c:\coding\fs\release\fs;        <br /></font><font face="Courier New" size="2">SRV*c:\symbols*http://msdl.microsoft.com/download/symbols</font></p> </blockquote>  <p>This tells the symbol decoder to look for symbols in the release build directory for FS.EXE and in the Windows public symbol server, caching the served symbols in c:\symbols.&#160; The xperf tools uses the symbol decoding libraries from the <a href="http://www.microsoft.com/whdc/DevTools/Debugging/default.mspx" target="_blank">debugging tools for Windows</a>.&#160; You can find more information on using symbols <a href="http://www.microsoft.com/whdc/devtools/debugging/debugstart.mspx" target="_blank">here</a>.</p>  <p>Once the trace is taken and the symbol path is set, then simply open the trace in Performance Analyzer with the command &quot;<strong><font face="Courier New" size="2">xperf profile.etl</font></strong>&quot;.&#160; </p>  <p><a href="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/BlogFileStorage/blogs_msdn/pigscanfly/WindowsLiveWriter/UsingWindowsSampleProfilerwithXperf_9E19/image_4.png" original-url="http://blogs.msdn.com/blogfiles/pigscanfly/WindowsLiveWriter/UsingWindowsSampleProfilerwithXperf_9E19/image_4.png"><img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; margin: 0px 0px 0px 5px; border-right-width: 0px" height="112" alt="image" src="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/BlogFileStorage/blogs_msdn/pigscanfly/WindowsLiveWriter/UsingWindowsSampleProfilerwithXperf_9E19/image_thumb_1.png" original-url="http://blogs.msdn.com/blogfiles/pigscanfly/WindowsLiveWriter/UsingWindowsSampleProfilerwithXperf_9E19/image_thumb_1.png" width="235" align="right" border="0" /></a>The CPU Sampling by Process graph is the most interesting graph for this example.&#160; To select the visible graphs, click on the flyout control on the left of the window, then select the CPU Sampling by CPU, and by Process graphs.</p>  <p>For his experiment, the CPU sampling by Process graph looks like this:</p>  <p><a href="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/BlogFileStorage/blogs_msdn/pigscanfly/WindowsLiveWriter/UsingWindowsSampleProfilerwithXperf_9E19/image_36.png" original-url="http://blogs.msdn.com/blogfiles/pigscanfly/WindowsLiveWriter/UsingWindowsSampleProfilerwithXperf_9E19/image_36.png"><img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="126" alt="image" src="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/BlogFileStorage/blogs_msdn/pigscanfly/WindowsLiveWriter/UsingWindowsSampleProfilerwithXperf_9E19/image_thumb_17.png" original-url="http://blogs.msdn.com/blogfiles/pigscanfly/WindowsLiveWriter/UsingWindowsSampleProfilerwithXperf_9E19/image_thumb_17.png" width="538" border="0" /></a> </p>  <p>By default, all processes running during the trace are shown except the idle task (as seen above).&#160; You can change which processes are displayed or hidden by by using the check boxes in the legend drop down as shown above.</p>  <p>This graph illustrates an important concept about the kernel event provider and the xperf tools in general - they are specifically designed to analyze system wide and application performance data and events.&#160; For example, in the legend above, there are many processes listed, but only a few of them actually used any CPU time during the experiment. </p>  <p>Using the legend, you can eliminate all processes except the interesting one.&#160;&#160; Here is what the graph of CPU utilization for only FS.EXE looks like</p>  <p><a href="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/BlogFileStorage/blogs_msdn/pigscanfly/WindowsLiveWriter/UsingWindowsSampleProfilerwithXperf_9E19/image_10.png" original-url="http://blogs.msdn.com/blogfiles/pigscanfly/WindowsLiveWriter/UsingWindowsSampleProfilerwithXperf_9E19/image_10.png"><img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="209" alt="image" src="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/BlogFileStorage/blogs_msdn/pigscanfly/WindowsLiveWriter/UsingWindowsSampleProfilerwithXperf_9E19/image_thumb_4.png" original-url="http://blogs.msdn.com/blogfiles/pigscanfly/WindowsLiveWriter/UsingWindowsSampleProfilerwithXperf_9E19/image_thumb_4.png" width="523" border="0" /></a> </p>  <p>This is pretty cool as it provides a nice overview of the CPU utilization of FS.EXE, but it really doesn't tell us much about where time is being spent in the process it self.</p>  <p>The real power in Performance Analyzer is in its summary tables.&#160; These are tabular displays of data about a specific chart, or a region in a chart.&#160; For this experiment, I looked at the sample profile data for the entire trace.&#160; To do this, right mouse click on the CPU Sampling by Process chart, make sure that the load symbols option is set, then select the Summary table view. </p>  <p><a href="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/BlogFileStorage/blogs_msdn/pigscanfly/WindowsLiveWriter/UsingWindowsSampleProfilerwithXperf_9E19/image_12.png" original-url="http://blogs.msdn.com/blogfiles/pigscanfly/WindowsLiveWriter/UsingWindowsSampleProfilerwithXperf_9E19/image_12.png"><img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="212" alt="image" src="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/BlogFileStorage/blogs_msdn/pigscanfly/WindowsLiveWriter/UsingWindowsSampleProfilerwithXperf_9E19/image_thumb_5.png" original-url="http://blogs.msdn.com/blogfiles/pigscanfly/WindowsLiveWriter/UsingWindowsSampleProfilerwithXperf_9E19/image_thumb_5.png" width="529" border="0" /></a> </p>  <p>Note, it will take 10 to 20 seconds for the summary table to show up.&#160; Performance Analyzer is loading symbols while this is happening.&#160; (putting symbol loading on a background thread is on our to do list...).</p>  <p><a href="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/BlogFileStorage/blogs_msdn/pigscanfly/WindowsLiveWriter/UsingWindowsSampleProfilerwithXperf_9E19/image_14.png" original-url="http://blogs.msdn.com/blogfiles/pigscanfly/WindowsLiveWriter/UsingWindowsSampleProfilerwithXperf_9E19/image_14.png"><img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; margin: 0px 0px 0px 5px; border-right-width: 0px" height="103" alt="image" src="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/BlogFileStorage/blogs_msdn/pigscanfly/WindowsLiveWriter/UsingWindowsSampleProfilerwithXperf_9E19/image_thumb_6.png" original-url="http://blogs.msdn.com/blogfiles/pigscanfly/WindowsLiveWriter/UsingWindowsSampleProfilerwithXperf_9E19/image_thumb_6.png" width="108" align="right" border="0" /></a>After the summary table pops up, click on the flyout and select the columns for display.&#160; In this case you will want the process, stack and % Weight columns (feel free to experiment with other columns).&#160; </p>  <p>Next, arrange the columns as follows.&#160; The columns to the left of the gold column are grouping columns.&#160;&#160; You can change the order of columns and put them to the left or right of the gold column by dragging.</p>  <p><a href="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/BlogFileStorage/blogs_msdn/pigscanfly/WindowsLiveWriter/UsingWindowsSampleProfilerwithXperf_9E19/image_16.png" original-url="http://blogs.msdn.com/blogfiles/pigscanfly/WindowsLiveWriter/UsingWindowsSampleProfilerwithXperf_9E19/image_16.png"><img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="72" alt="image" src="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/BlogFileStorage/blogs_msdn/pigscanfly/WindowsLiveWriter/UsingWindowsSampleProfilerwithXperf_9E19/image_thumb_7.png" original-url="http://blogs.msdn.com/blogfiles/pigscanfly/WindowsLiveWriter/UsingWindowsSampleProfilerwithXperf_9E19/image_thumb_7.png" width="529" border="0" /></a> </p>  <p>Now, you can expand the stacks for FS.EXE and see where it is spending its time.&#160; Not that this isn't by function as in some profilers but by <u>call stack</u>.&#160; This is much more powerful than simply knowing the functions where time is spent as it also shows you how the time consuming functions were called.</p>  <p>Its no surprise that my find string utility spends most of its time in the following stack:</p>  <p><a href="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/BlogFileStorage/blogs_msdn/pigscanfly/WindowsLiveWriter/UsingWindowsSampleProfilerwithXperf_9E19/image_20.png" original-url="http://blogs.msdn.com/blogfiles/pigscanfly/WindowsLiveWriter/UsingWindowsSampleProfilerwithXperf_9E19/image_20.png"><img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="361" alt="image" src="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/BlogFileStorage/blogs_msdn/pigscanfly/WindowsLiveWriter/UsingWindowsSampleProfilerwithXperf_9E19/image_thumb_9.png" original-url="http://blogs.msdn.com/blogfiles/pigscanfly/WindowsLiveWriter/UsingWindowsSampleProfilerwithXperf_9E19/image_thumb_9.png" width="536" border="0" /></a>&#160;</p>  <p>As with other sample profilers, you can look &quot;up&quot; and &quot;down&quot; the stacks from any particular point. This is commonly called a butterfly view.&#160; Right mouse click on any item in the stack column and experiment with the <em>callers/callees</em> and <em>inntermost/outermost</em> options, like this:</p>  <p><a href="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/BlogFileStorage/blogs_msdn/pigscanfly/WindowsLiveWriter/UsingWindowsSampleProfilerwithXperf_9E19/image_22.png" original-url="http://blogs.msdn.com/blogfiles/pigscanfly/WindowsLiveWriter/UsingWindowsSampleProfilerwithXperf_9E19/image_22.png"><img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="206" alt="image" src="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/BlogFileStorage/blogs_msdn/pigscanfly/WindowsLiveWriter/UsingWindowsSampleProfilerwithXperf_9E19/image_thumb_10.png" original-url="http://blogs.msdn.com/blogfiles/pigscanfly/WindowsLiveWriter/UsingWindowsSampleProfilerwithXperf_9E19/image_thumb_10.png" width="452" border="0" /></a></p>  <p>This stack trace has very simple call stacks so it isn't very useful for looking at butterfly views.&#160; But try one of your own programs and look at a butterfly stack view of a function that is called often from multiple places.&#160;&#160; Or, use the butterfly view too look at a intermediate function and see all the functions it calls, and their stacks. </p>  <p>The above screen shots and summary table views contain the data from the entire trace.&#160;&#160; This works ok for short traces.&#160; But for longer traces, or even short traces with a lot of detail, we often need to look at specific time spans.&#160; </p>  <p>For example, there are some time spans in my experiment where FS isn't using very little CPU time.&#160; I'd like to see what FS is up to in that time span.&#160; This is easily done by using the left mouse button to select a time span on the X axis and zooming the graph to that view, or look at the summary table for that span, as in this example.</p>  <p><a href="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/BlogFileStorage/blogs_msdn/pigscanfly/WindowsLiveWriter/UsingWindowsSampleProfilerwithXperf_9E19/image_30.png" original-url="http://blogs.msdn.com/blogfiles/pigscanfly/WindowsLiveWriter/UsingWindowsSampleProfilerwithXperf_9E19/image_30.png"><img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="228" alt="image" src="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/BlogFileStorage/blogs_msdn/pigscanfly/WindowsLiveWriter/UsingWindowsSampleProfilerwithXperf_9E19/image_thumb_14.png" original-url="http://blogs.msdn.com/blogfiles/pigscanfly/WindowsLiveWriter/UsingWindowsSampleProfilerwithXperf_9E19/image_thumb_14.png" width="531" border="0" /></a> </p>  <p><a href="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/BlogFileStorage/blogs_msdn/pigscanfly/WindowsLiveWriter/UsingWindowsSampleProfilerwithXperf_9E19/image_32.png" original-url="http://blogs.msdn.com/blogfiles/pigscanfly/WindowsLiveWriter/UsingWindowsSampleProfilerwithXperf_9E19/image_32.png"><img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; margin: 0px 0px 0px 5px; border-right-width: 0px" height="118" alt="image" src="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/BlogFileStorage/blogs_msdn/pigscanfly/WindowsLiveWriter/UsingWindowsSampleProfilerwithXperf_9E19/image_thumb_15.png" original-url="http://blogs.msdn.com/blogfiles/pigscanfly/WindowsLiveWriter/UsingWindowsSampleProfilerwithXperf_9E19/image_thumb_15.png" width="163" align="right" border="0" /></a>Once the interesting region is selected, I simply use the right mouse button to pop up the context menu and select summary table.&#160; </p>  <p>Note that you can open up multiple summary tables, each from different regions of a graph, or even different graphs.&#160; This is great for making comparisons.</p>  <p>The new summary table window now only shows the data for selected time span in the trace.&#160; Is not surprising that FS is spending the little CPU time it is using in user mode asynchronous procedure calls. </p>  <p><a href="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/BlogFileStorage/blogs_msdn/pigscanfly/WindowsLiveWriter/UsingWindowsSampleProfilerwithXperf_9E19/image_34.png" original-url="http://blogs.msdn.com/blogfiles/pigscanfly/WindowsLiveWriter/UsingWindowsSampleProfilerwithXperf_9E19/image_34.png"><img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="288" alt="image" src="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/BlogFileStorage/blogs_msdn/pigscanfly/WindowsLiveWriter/UsingWindowsSampleProfilerwithXperf_9E19/image_thumb_16.png" original-url="http://blogs.msdn.com/blogfiles/pigscanfly/WindowsLiveWriter/UsingWindowsSampleProfilerwithXperf_9E19/image_thumb_16.png" width="536" border="0" /></a> </p>  <p>This post illustrates some key concepts:</p>  <ul>   <li>The xperf tools are designed for both system wide and application specific analysis. </li>    <li>Profiling with ETW is very, very light weight.&#160; While the experiment is running, the xperf tools are not even loaded - the kernel itself is collecting the data.&#160;&#160; All analysis is done as post processing tasks. </li>    <li>OS based sample profiling collects both user and kernel mode stacks.&#160;&#160; </li>    <li>So long as you have symbols, production code can be profiled - no special debug or instrumented builds are required. </li>    <li>In this example, I started and stopped FS.exe (the experiment) between the tracing start and stop.&#160; But, since this is ETW based, sample profiling can be started and stopped at any time, without stopping or restating even a single process.&#160; You can profile anything at any time on any system. </li>    <li>Stack views provide a very powerful method for analyzing where time is spent in a process. </li>    <li>The general technique with Performance Analyzer is to use the graphics to identify interesting time spans in the trace, then use the summary tables to look at the data in detail. </li> </ul>  <div class="wlWriterSmartContent" id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:0a4849cb-6ab2-401e-8382-df6f25b204c5" style="padding-right: 0px; display: inline; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px">del.icio.us Tags: <a href="http://del.icio.us/popular/performance" rel="tag">performance</a>,<a href="http://del.icio.us/popular/windows" rel="tag">windows</a>,<a href="http://del.icio.us/popular/tools" rel="tag">tools</a>,<a href="http://del.icio.us/popular/xperf" rel="tag">xperf</a></div>]]></content:encoded>
    </item>
  </channel>
</rss>