<?xml version="1.0" encoding="utf-8"?>
<rss xmlns:atom="https://www.w3.org/2005/Atom" xmlns:sy="https://purl.org/rss/1.0/modules/syndication/" xmlns:dc="https://purl.org/dc/elements/1.1/" xmlns:content="https://purl.org/rss/1.0/modules/content/" xmlns:wfw="https://wellformedweb.org/CommentAPI/" xmlns:slash="https://purl.org/rss/1.0/modules/slash/"
  version="2.0">
  <channel>
    <title>MarioHewardt</title>
    <atom:link
      href="https://docs.microsoft.com/archive/blogs/mariohewardt/feed.xml"
      rel="self"
      type="application/rss+xml" />
    <link>https://docs.microsoft.com/archive/blogs/mariohewardt/feed.xml</link>
    <description />
    <lastBuildDate>Wed, 17 Apr 2019 04:22:37 GMT</lastBuildDate>
    <language>en-US</language>
    <sy:updatePeriod>hourly</sy:updatePeriod>
    <sy:updateFrequency>1</sy:updateFrequency>
    <item>
      <title>No More Memory Fragmentation on the .NET Large Object Heap</title>
      <link>https://docs.microsoft.com/archive/blogs/mariohewardt/no-more-memory-fragmentation-on-the-net-large-object-heap</link>
      <pubDate>Wed, 26 Jun 2013 09:54:00 GMT</pubDate>
      <dc:creator><![CDATA[Mario Hewardt]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/mariohewardt/2013/06/26/no-more-memory-fragmentation-on-the-net-large-object-heap/</guid>
      <description><![CDATA[There are two different "types" of heaps in .NET. The Small Object Heap (SOH) and the Large Object...]]></description>
      <content:encoded><![CDATA[<p>There are two different "types" of heaps in .NET. The Small Object Heap (SOH) and the Large Object Heap (LOH). One of the key differences between the heaps is that the SOH compacts memory and hence reduces the chance of memory fragmentation dramatically while the LOH does not employ compaction. As a result, excessive usage of the LOH may result in memory fragmentation that can become severe enough to cause problems in applications. In order to avoid potential memory fragmentation on the LOH, developers can use various techniques that involve writing additional code. With the advent of the newly released .NET Framework 4.5.1 (Preview), developers can now tell the CLR (garbage collector) to compact the LOH thereby avoiding memory fragmentation.</p>
<p>.NET 4.5.1 Preview now includes a new enumeration called <span style="font-family: courier new,courier;">GCLargeObjectHeapCompactionMode</span> that has two fields:</p>
<ul>
<li><span style="font-family: courier new,courier;">CompactOnce</span> - The next time a full GC occurs the LOH will be compacted. Once done, it reverts back to the default behavior which is non compacting.</li>
<li><span style="font-family: courier new,courier;">Default</span> - Default behavior is non compacting.</li>
</ul>
<p>&nbsp;</p>
<p>In order to set the LOH compaction mode using the enum above, simply use the <span style="font-family: courier new,courier;">GCSettings</span> class and its corresponding <span style="font-family: courier new,courier;">LargeObjectHeapCompactionMode</span> property:</p>
<p><span style="font-family: courier new,courier;">GCSettings.LargeObjectHeapCompactionMode = GCLargeObjectHeapCompactionMode.CompactOnce;</span></p>
<p><span style="font-family: courier new,courier;">GC.Collect();&nbsp;&nbsp;&nbsp;&nbsp; // This will cause the LOH to be compacted (once).</span></p>
<p>&nbsp;</p>
<p>The .NET 4.5.1 Preview can be downloaded from: <a href="https://www.microsoft.com/visualstudio/eng/2013-downloads">https://www.microsoft.com/visualstudio/eng/2013-downloads</a></p>
<p>&nbsp;As always, please note that this is a Preview release and as such functionality and behavior is subject to change.</p>
<p>&nbsp;</p>]]></content:encoded>
    </item>
    <item>
      <title>More Efficiently Debug the Managed Heap Using SOS 4.5</title>
      <link>https://docs.microsoft.com/archive/blogs/mariohewardt/more-efficiently-debug-the-managed-heap-using-sos-4-5</link>
      <pubDate>Wed, 13 Mar 2013 15:27:00 GMT</pubDate>
      <dc:creator><![CDATA[Mario Hewardt]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/mariohewardt/2013/03/13/more-efficiently-debug-the-managed-heap-using-sos-4-5/</guid>
      <description><![CDATA[More often than not, when we investigate the managed heap using SOS we use the all powerful...]]></description>
      <content:encoded><![CDATA[<p><span style="font-family: arial,helvetica,sans-serif;">More often than not, when we investigate the managed heap using SOS we use the all powerful !DumpHeap command. It's an incredibly useful command to get in depth detail on what currently resides on the heap. Let's look at an example of&nbsp;the abbreviated&nbsp;output from !DumpHeap -stat:</span></p>
<p>&nbsp;</p>
<p><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; MT&nbsp;&nbsp;&nbsp; Count&nbsp;&nbsp;&nbsp; TotalSize Class Name</span></p>
<p><span style="font-family: courier new,courier;">...</span></p>
<p><span style="font-family: courier new,courier;">...</span></p>
<p><span style="font-family: courier new,courier;">737bc460&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 26&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 728 System.RuntimeType</span><br /><span style="font-family: courier new,courier;">737bca30&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 12&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 768 System.Int32[]</span><br /><span style="font-family: courier new,courier;">737bca68&nbsp;&nbsp;&nbsp; 51661&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 619932 System.Int32</span><br /><span style="font-family: courier new,courier;">7376b180&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 31&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 935720 System.Object[]</span><br /><span style="font-family: courier new,courier;">0055cf08&nbsp;&nbsp;&nbsp; 48361&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1771906&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Free</span><br /><span style="font-family: courier new,courier; background-color: #ffff00;">737bb2a8&nbsp;&nbsp; 151831&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 6022544 System.String</span></p>
<p><span style="font-family: arial,helvetica,sans-serif;">The highlighted line above tells us that we have roughly 150,000 instances of strings on the managed heap that occupies about 6MB of memory. Not a huge amount of memory but concerning nonetheless since in this particular application I don't expect it to ever have this many instances of a string type laying around. Hence, my conclusion is that we are somehow "leaking" (or rather, holding on to for far too long) 150,000 instances of strings when we shouldn't be. Now it's a simple matter of figuring out who references those instances and why. Or is it really that simple? If we step back and think about what<span style="font-family: courier new,courier;"> !DumpHeap -stat</span> is telling us - there are 150,000 instances of strings but it doesn't tell us anything whether those instances are still alive or not. For example, a good chunk of the above instances might not be referenced and are therefore eligible for garbage collection. In those cases, we're not really interested in investigating further since they are about to get cleaned up. How do we know which instances (out of the 150,000) are alive or dead? Well, we can certainly run <span style="font-family: courier new,courier;">!gcroot</span> on all of them but chances that by the time you got to instance 10 you'd be falling asleep at the wheel. Luckily - in SOS 4.5 there are two additional switches to the <span style="font-family: courier new,courier;">!DumpHeap</span> command:</span></p>
<ul>
<li><span style="font-family: arial,helvetica,sans-serif;"><span style="font-family: courier new,courier;">-live</span> : Indicates that you only want <span style="font-family: courier new,courier;">!DumpHeap</span> to output instances that are considered alive.</span></li>
<li><span style="font-family: arial,helvetica,sans-serif;"><span style="font-family: courier new,courier;">-dead</span> : Indicates that you only want<span style="font-family: courier new,courier;"> !DumpHeap</span> to output instances that are considered dead (and therefore eligible for garbage collection).</span></li>
</ul>
<p>With those two switches, our exercise now goes from spending a ridiculous amount of time manually running<span style="font-family: courier new,courier;"> !gcroot</span> to simply adding the<span style="font-family: courier new,courier;"> -live</span> (or <span style="font-family: courier new,courier;">-dead</span>) switch. In the example above, once I ran <span style="font-family: courier new,courier;">!DumpHeap -stat -mt 737bb2a8 -live</span> I got the following output:</p>
<p><span style="font-family: courier new,courier;">0:005&gt; !DumpHeap -stat -mt 737bb2a8 -live</span><br /><span style="font-family: courier new,courier;">Statistics:</span><br /><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; MT&nbsp;&nbsp;&nbsp; Count&nbsp;&nbsp;&nbsp; TotalSize Class Name</span><br /><span style="font-family: courier new,courier;">737bb2a8&nbsp;&nbsp; 100167&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 4782606 System.String</span><br /><span style="font-family: courier new,courier;">Total <span style="background-color: #ffff00;">100167</span> objects</span></p>
<p><span style="font-family: arial,helvetica,sans-serif;">This means that out of the total of 150,000 instances 100,000 are considered alive and the rest will eventually be garbage collected.</span></p>
<p>The addition of -live/-dead switches to !DumpHeap can save a great deal of time when chasing down which objects on the managed heap are considered dead/alive and can dramatically reduce the amount of time spent on debugging excessive memory usage in .NET applications.</p>
<p>Happy Debugging!</p>
<p>&nbsp;</p>]]></content:encoded>
    </item>
    <item>
      <title>Visual Studio 2012 and Parallel Watch Window</title>
      <link>https://docs.microsoft.com/archive/blogs/mariohewardt/visual-studio-2012-and-parallel-watch-window</link>
      <pubDate>Mon, 11 Jun 2012 10:55:29 GMT</pubDate>
      <dc:creator><![CDATA[Mario Hewardt]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/mariohewardt/2012/06/11/visual-studio-2012-and-parallel-watch-window/</guid>
      <description><![CDATA[Traditionally, debuggers have been very per thread centric. For example, a debugger most typically...]]></description>
      <content:encoded><![CDATA[<p>Traditionally, debuggers have been very per thread centric. For example, a debugger most typically will assign a thread to be the current thread and any thread related debug operations you perform will be done on the selected thread. In order to work with a different thread, you need to first switch the thread context. One of the ways that you were able to switch the active thread in Visual Studio was to bring up the Threads Window and double click on the thread of interest. While this works fine for applications with relatively few threads, it becomes cumbersome for heavily multithreaded applications. Luckily, Visual Studio 2012 RC has a feature known as Parallel Watch Window that aids greatly in these scenarios.</p>  <p>At a high level, a watch window allows you to watch the results of expressions. The expressions can be as simple as the value of a local variable but can also be much more complicated. Imagine we have the following simple code that multiple threads execute concurrently:</p>  <p>&#160;</p>  <p>private static void WorkThreadFunction()   <br />{    <br />&#160;&#160;&#160; for (int i = 0; i &lt; max_list_len; i++)    <br />&#160;&#160;&#160; {    <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; // Do work&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <br />&#160;&#160;&#160; }    <br />}</p>  <p>&#160;</p>  <p>Nothing too fancy – simply multiple threads iterating through a list of some sort. Now, lets say that 25 threads were currently executing the function above and we want to see at which iteration (‘i’) each of the threads is currently executing. Previously we would have to switch the active thread context 25 times and record the value of ‘i’ somewhere. Instead, with Visual Studio 2012 RC we can bring up the Parallel Watch Window as shown below:</p>  <p>&#160;</p>  <p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/53/23/metablogapi/3566.image_11C3DE01.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-53-23-metablogapi/3566.image_5F00_11C3DE01.png"><img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/53/23/metablogapi/5621.image_thumb_1876E784.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-53-23-metablogapi/5621.image_5F00_thumb_5F00_1876E784.png" width="1075" height="446" /></a> </p>  <p>&#160;</p>  <p>Choosing Parallel Watch Window 1 (there are four to choose from) displays the Watch Window:</p>  <p>&#160;</p>  <p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/53/23/metablogapi/0434.image_3C300F1E.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-53-23-metablogapi/0434.image_5F00_3C300F1E.png"><img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/53/23/metablogapi/8666.image_thumb_10EB7817.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-53-23-metablogapi/8666.image_5F00_thumb_5F00_10EB7817.png" width="646" height="389" /></a> </p>  <p></p>  <p>&#160;</p>  <p>By default, the Parallel Watch Window brings up all the thread currently executing in the process. In order to add new watches, we need to click “&lt;Add Watch&gt;” column which allows us to enter an expression. In our case, the expression is as simple as showing the local variable ‘i’:</p>  <p>&#160;</p>  <p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/53/23/metablogapi/2313.image_09CC3B9F.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-53-23-metablogapi/2313.image_5F00_09CC3B9F.png"><img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/53/23/metablogapi/1325.image_thumb_309A51DF.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-53-23-metablogapi/1325.image_5F00_thumb_5F00_309A51DF.png" width="652" height="393" /></a> </p>  <p>&#160;</p>  <p>As soon as the watch is added we can now see the expression evaluated across all the different threads in the watch window:</p>  <p>&#160;</p>  <p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/53/23/metablogapi/2402.image_4276E5AC.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-53-23-metablogapi/2402.image_5F00_4276E5AC.png"><img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/53/23/metablogapi/8863.image_thumb_21EFA5FA.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-53-23-metablogapi/8863.image_5F00_thumb_5F00_21EFA5FA.png" width="661" height="401" /></a> </p>  <p></p>  <p>&#160;</p>  <p>Another interesting aspect of the Parallel Watch Window is that you can sort the columns as well as adding a filter to the watch (Filter by Boolean Expression).</p>  <p>&#160;</p>  <p>This is a pretty powerful and time saving feature if you spend lots of time doing multithreaded debugging.</p>  <p>&#160;</p>  <p>Until next time, happy debugging!</p>]]></content:encoded>
    </item>
    <item>
      <title>Visual Studio 2012 and WinDbg Integration</title>
      <link>https://docs.microsoft.com/archive/blogs/mariohewardt/visual-studio-2012-and-windbg-integration</link>
      <pubDate>Tue, 05 Jun 2012 09:49:19 GMT</pubDate>
      <dc:creator><![CDATA[Mario Hewardt]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/mariohewardt/2012/06/05/visual-studio-2012-and-windbg-integration/</guid>
      <description><![CDATA[Microsoft has always provided two primary debugging experience: Visual Studio and Debugging Tools...]]></description>
      <content:encoded><![CDATA[<p>Microsoft has always provided two primary debugging experience: Visual Studio and Debugging Tools for Windows (a.k.a WinDbg). Each debugger provided a very different debugging experience (both from a capabilities point of view as well as usability). WinDbg was most commonly used when you had the need for low level debugging and was also not very user friendly requiring a steep learning curve. Visual Studio on the other hand was a very user friendly type of debugger but not always suited for low level type of debugging. Fortunately, with the introduction of Visual Studio 2012 (beta) both experiences are now folded into the Visual Studio debugger. </p>  <p>To start using the powerful WinDbg commands and extensions in Visual Studio 2012 it requires that you install the WDK on top of Visual Studio 2012. Once the install is completed you will notice a new transport as shown below:</p>  <p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/53/23/metablogapi/7271.image_5B8F8E39.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-53-23-metablogapi/7271.image_5F00_5B8F8E39.png"><img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/53/23/metablogapi/2072.image_thumb_4AF7934B.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-53-23-metablogapi/2072.image_5F00_thumb_5F00_4AF7934B.png" width="859" height="333" /></a></p>  <p>In the transport dropdown there will be several new choices including Windows User Mode Debugger which is what you want to pick to enable the WinDbg experience. Once you select your process and click attach the debugger immediate window will be displayed and serves essentially the same purpose as the WinDbg command window:</p>  <p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/53/23/metablogapi/3036.image_2D65B84C.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-53-23-metablogapi/3036.image_5F00_2D65B84C.png"><img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/53/23/metablogapi/7752.image_thumb_5A5B1B27.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-53-23-metablogapi/7752.image_5F00_thumb_5F00_5A5B1B27.png" width="858" height="214" /></a></p>  <p>You can now execute all the cool and powerful commands that you would otherwise do in WinDbg directly in the debugger immediate window! This is a great step forward to unifying the debugging experience and avoiding the need to learn two different tools.</p>  <p>Until next time, happy debugging!</p>  <p>&#160;</p>  <p><strong>UPDATE: </strong></p>  <p>Some users are reporting that the Windows User Mode Debugger is not showing up as a transport option. On Visual Studio 2012 <strong>RC</strong> it looks like you must also install the Windows SDK for this option to appear. </p>]]></content:encoded>
    </item>
    <item>
      <title>The Non Blocking Monitor Wait</title>
      <link>https://docs.microsoft.com/archive/blogs/mariohewardt/the-non-blocking-monitor-wait</link>
      <pubDate>Thu, 31 May 2012 16:43:29 GMT</pubDate>
      <dc:creator><![CDATA[Mario Hewardt]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/mariohewardt/2012/05/31/the-non-blocking-monitor-wait/</guid>
      <description><![CDATA[&#160;  One of key things we are taught about lock constructs in general is that a thread will...]]></description>
      <content:encoded><![CDATA[<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/53/23/metablogapi/7080.goal_2787D2D6.jpg" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-53-23-metablogapi/7080.goal_5F00_2787D2D6.jpg"><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="" border="0" alt="" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/53/23/metablogapi/5736.goal_thumb_01A186A6.jpg" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-53-23-metablogapi/5736.goal_5F00_thumb_5F00_01A186A6.jpg" width="244" height="160" /></a></p>  <p>&#160;</p>  <p>One of key things we are taught about lock constructs in general is that a thread will wait indefinitely on a lock to become available before being allowed to continue. Is that <strong>always </strong>true? Not quite. Let’s take a look at a simple piece of code:</p>  <p><font face="Courier New"></font></p>  <p><font size="2" face="Courier New">private void webBrowser1_Navigating(object sender, WebBrowserNavigatingEventArgs e)     <br />{</font></p>  <blockquote>   <p><font size="2" face="Courier New">…</font></p>    <p><font size="2" face="Courier New">lock(someObj)</font></p>    <p><font size="2" face="Courier New">{</font></p> </blockquote>  <blockquote>   <p><font size="2" face="Courier New">}</font></p> </blockquote>  <p><font size="2" face="Courier New">}     <br /></font></p>  <p>&#160;</p>  <p>The intent behind the code is rather simple – protect the resources by using a .NET Monitor (under the covers, the lock keyword is just syntactic sugar for entering a Monitor). If a thread already holds the lock, all other threads will wait until it becomes available again before one of the waiting threads is awoken and allowed to continue.&#160; Now, let’s assume that the code was running on the main UI thread and that the lock was already held by a non UI thread. Based on what we know about the Monitor, the UI thread would wait indefinitely for the lock to become available.&#160; The net result must be a frozen UI (thread is blocked waiting and not pumping messages). </p>  <p>Almost – it turns out that in the case of a main UI thread (STA) the blocking thread can be woken up for another reason besides the lock becoming available. Let’s take a look at the (abbreviated) stack trace when this occurs to get a better idea of how it works internally:</p>  <p><font face="Courier New"><font style="background-color: #ffff00">System.Threading.Monitor.ReliableEnter       <br />System.Threading.Monitor.Enter        <br />BrowseApp.Form1.webBrowser1_Navigating        <br /></font>System.Windows.Forms.WebBrowser.OnNavigating      <br />System.Windows.Forms.WebBrowser+WebBrowserEvent.BeforeNavigate2      <br />System.RuntimeMethodHandle.InvokeMethod      <br />System.Reflection.RuntimeMethodInfo.Invoke      <br />System.Windows.Forms.UnsafeNativeMethods.CallWindowProc      <br />System.Windows.Forms.NativeWindow.DefWndProc      <br />System.Windows.Forms.WebBrowserBase+WebBrowserBaseNativeWindow.WndProc      <br />System.Windows.Forms.NativeWindow.Callback      <br /><font style="background-color: #ffff00">System.Threading.Monitor.ReliableEnter       <br />System.Threading.Monitor.Enter        <br />BrowseApp.Form1.webBrowser1_Navigating        <br /></font>System.Windows.Forms.WebBrowser.OnNavigating      <br />System.Windows.Forms.WebBrowser+WebBrowserEvent.BeforeNavigate2      <br />System.RuntimeMethodHandle.InvokeMethod      <br />System.Reflection.RuntimeMethodInfo.Invoke      <br />System.Reflection.RuntimeMethodInfo.Invoke      <br />System.Windows.Forms.UnsafeNativeMethods.CallWindowProc      <br />System.Windows.Forms.NativeWindow.DefWndProc      <br />System.Windows.Forms.WebBrowserBase+WebBrowserBaseNativeWindow.WndProc      <br />System.Windows.Forms.NativeWindow.Callback      <br /><font style="background-color: #ffff00">System.Threading.Monitor.ReliableEnter       <br />System.Threading.Monitor.Enter        <br />BrowseApp.Form1.webBrowser1_Navigating        <br /></font>System.Windows.Forms.WebBrowser.OnNavigating      <br />System.Windows.Forms.WebBrowser+WebBrowserEvent.BeforeNavigate2      <br />System.RuntimeMethodHandle.InvokeMethod      <br />System.Reflection.RuntimeMethodInfo.Invoke      <br />System.Reflection.RuntimeMethodInfo.Invoke</font></p>  <p>&lt;snip&gt;</p>  <p>&#160;</p>  <p>The highlighted frames seem to be repeating themselves a number of times. Our <font face="Courier New">webBrowser1_Navigating</font> method that should have been waiting on a lock to become available somehow was woken up. It’s clear from the call stack what caused it to be woken up was due to the thread continuously pumping window messages (and each message in turn caused the same navigation method to be executed). What is not clear though is how that actually happens. How can a thread that is blocking be woken up? The answer lies in the API that the CLR uses to perform the wait. Instead of using an API such as WaitForSingleObject it uses the API highlighted below: </p>  <p><font face="Courier New">&#160;</font></p>  <p><font face="Courier New">USER32!InternalCallWinProc+0x23     <br />USER32!UserCallWinProcCheckWow+0x109      <br />USER32!DispatchMessageWorker+0x3bc      <br />USER32!DispatchMessageW+0xf      <br />ole32!CCliModalLoop::PeekRPCAndDDEMessage+0x4c      <br />ole32!CCliModalLoop::BlockFn+0x6c      <br /></font><font face="Courier New"><font style="background-color: #ffff00">ole32!CoWaitForMultipleHandles+0xcd       <br /></font>clr!MsgWaitHelper+0x64      <br />clr!Thread::DoAppropriateWaitWorker+0x21c      <br />clr!Thread::DoAppropriateWait+0x65      <br />clr!CLREventBase::WaitEx+0x128      <br />clr!CLREventBase::Wait+0x1a</font></p>  <p>&#160;</p>  <p>The API <font face="Courier New">CoWaitForMultipleHandles</font> is able to pump messages while it’s waiting and thereby make sure that the UI is responsive. What is the big fuzz then? This is great news! On a main UI thread we can block on a lock but also make sure the UI is responsive while blocking. The biggest problem with this approach is that you have to be extremely careful about what type and how many messages are pumped while you are in a blocked state. Imagine that the lock was held for quite some time and during that time 100’s of navigation events fired. What you would essentially see is a big call stack with the above frames repeating themselves. What is the problem with a big call stack? Stack space. If there are enough of these messages processed you will eventually run out of stack space and crash with a stack overflow exception:</p>  <p><font face="Courier New">(2eb0.1d88): Stack overflow - code c00000fd (first chance)     <br />First chance exceptions are reported before any exception handling.      <br />This exception may be expected and handled.</font></p>  <p>&#160;</p>  <p>To get around this problem, you can relatively easily change the waiting/blocking behavior of the CLR by using the SynchronizationContext class. In a future blog post I will describe a reusable solution to does just this.</p>  <p>&#160;</p>  <p>Until next time, happy debugging!</p>]]></content:encoded>
    </item>
  </channel>
</rss>