<?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>Speaking of which...</title>
    <atom:link
      href="https://docs.microsoft.com/archive/blogs/johan/feed.xml"
      rel="self"
      type="application/rss+xml" />
    <link>https://docs.microsoft.com/archive/blogs/johan/feed.xml</link>
    <description>Sample solutions from Internet development support</description>
    <lastBuildDate>Wed, 24 Feb 2016 14:47:44 GMT</lastBuildDate>
    <language>en-US</language>
    <sy:updatePeriod>hourly</sy:updatePeriod>
    <sy:updateFrequency>1</sy:updateFrequency>
    <item>
      <title>Changing file dates and other more uncommon properties in PowerShell</title>
      <link>https://docs.microsoft.com/archive/blogs/johan/changing-file-dates-and-other-more-uncommon-properties-in-powershell</link>
      <pubDate>Thu, 29 Dec 2011 07:17:47 GMT</pubDate>
      <dc:creator><![CDATA[JohanSt]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/johan/2011/12/29/changing-file-dates-and-other-more-uncommon-properties-in-powershell/</guid>
      <description><![CDATA[There are some file properties that aren’t too easy to change. Neither in the command line or in...]]></description>
      <content:encoded><![CDATA[<p>There are some file properties that aren’t too easy to change. Neither in the command line or in Windows Explorer. One that I’ve wanted to change personally quite often is the created and changed dates of a specific file, or a batch of files.</p>  <h1>Background</h1>  <p>I frequently use my Windows Phone (currently a Nokia Lumia 800) for listening to audio books. I’ve found that the best way to do so is to change the category of the files to “podcast” and they’ll show up as podcasts and I won’t have to keep track of where I was, etc. since Zune will do that for me. Zune uses the creation date to order the files in a podcast, and some times the creation dates of my files may not be entirely correct. There are a lot of shareware programs that will allow you to do batch updates on files and change these properties, but it’s actually a lot easier to do it yourself in PowerShell</p>  <h1>How to fix this</h1>  <p>If you have the files sorted the way you want alphabetically and want to order them by creation date in the same way, then this is a pretty easy way to do it.</p>  <div class="SampleCode">$files = dir    <br />for($i=0;$i -le $files.GetUpperBound(0); $i++)     <br />{     <br />&#160;&#160; ($files[$i]).CreationTime = (get-date).AddSeconds($i)     <br />&#160;&#160; ($files[$i]).LastWriteTime = (get-date).AddSeconds($i)     <br />}     <br /></div>  <p>Naturally you could alter other properties as well simply pass one of the objects into get-method to see what’s available:</p>  <div class="SampleCode">Name&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; MemberType&#160;&#160;&#160;&#160; Definition    <br />----&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; ----------&#160;&#160;&#160;&#160; ----------     <br />Mode&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; CodeProperty&#160;&#160; System.String Mode{get=Mode;}     <br />Create&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; Method&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; System.Void Create(System.Security.AccessControl.DirectorySecurity director...     <br />CreateObjRef&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; Method&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; System.Runtime.Remoting.ObjRef CreateObjRef(type requestedType)     <br />CreateSubdirectory&#160;&#160;&#160;&#160;&#160;&#160;&#160; Method&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; System.IO.DirectoryInfo CreateSubdirectory(string path), System.IO.Director...     <br />Delete&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; Method&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; System.Void Delete(), System.Void Delete(bool recursive)     <br />Equals&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; Method&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; bool Equals(System.Object obj)     <br />GetAccessControl&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; Method&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; System.Security.AccessControl.DirectorySecurity GetAccessControl(), System....     <br />GetDirectories&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; Method&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; System.IO.DirectoryInfo[] GetDirectories(string searchPattern), System.IO.D...     <br />GetFiles&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; Method&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; System.IO.FileInfo[] GetFiles(string searchPattern), System.IO.FileInfo[] G...     <br />GetFileSystemInfos&#160;&#160;&#160;&#160;&#160;&#160;&#160; Method&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; System.IO.FileSystemInfo[] GetFileSystemInfos(string searchPattern), System...     <br />GetHashCode&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; Method&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; int GetHashCode()     <br />GetLifetimeService&#160;&#160;&#160;&#160;&#160;&#160;&#160; Method&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; System.Object GetLifetimeService()     <br />GetObjectData&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; Method&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; System.Void GetObjectData(System.Runtime.Serialization.SerializationInfo in...     <br />GetType&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; Method&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; type GetType()     <br />InitializeLifetimeService Method&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; System.Object InitializeLifetimeService()     <br />MoveTo&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; Method&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; System.Void MoveTo(string destDirName)     <br />Refresh&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; Method&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; System.Void Refresh()     <br />SetAccessControl&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; Method&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; System.Void SetAccessControl(System.Security.AccessControl.DirectorySecurit...     <br />ToString&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; Method&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; string ToString()     <br />PSChildName&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; NoteProperty&#160;&#160; System.String PSChildName=.gimp-2.6     <br />PSDrive&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; NoteProperty&#160;&#160; System.Management.Automation.PSDriveInfo PSDrive=C     <br />PSIsContainer&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; NoteProperty&#160;&#160; System.Boolean PSIsContainer=True     <br />PSParentPath&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; NoteProperty&#160;&#160; System.String PSParentPath=Microsoft.PowerShell.Core\FileSystem::C:\Users\j...     <br />PSPath&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; NoteProperty&#160;&#160; System.String PSPath=Microsoft.PowerShell.Core\FileSystem::C:\Users\jstraar...     <br />PSProvider&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; NoteProperty&#160;&#160; System.Management.Automation.ProviderInfo PSProvider=Microsoft.PowerShell.C...     <br />Attributes&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; Property&#160;&#160;&#160;&#160;&#160;&#160; System.IO.FileAttributes Attributes {get;set;}     <br />CreationTime&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; Property&#160;&#160;&#160;&#160;&#160;&#160; System.DateTime CreationTime {get;set;}     <br />CreationTimeUtc&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; Property&#160;&#160;&#160;&#160;&#160;&#160; System.DateTime CreationTimeUtc {get;set;}     <br />Exists&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; Property&#160;&#160;&#160;&#160;&#160;&#160; System.Boolean Exists {get;}     <br />Extension&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; Property&#160;&#160;&#160;&#160;&#160;&#160; System.String Extension {get;}     <br />FullName&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; Property&#160;&#160;&#160;&#160;&#160;&#160; System.String FullName {get;}     <br />LastAccessTime&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; Property&#160;&#160;&#160;&#160;&#160;&#160; System.DateTime LastAccessTime {get;set;}     <br />LastAccessTimeUtc&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; Property&#160;&#160;&#160;&#160;&#160;&#160; System.DateTime LastAccessTimeUtc {get;set;}     <br />LastWriteTime&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; Property&#160;&#160;&#160;&#160;&#160;&#160; System.DateTime LastWriteTime {get;set;}     <br />LastWriteTimeUtc&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; Property&#160;&#160;&#160;&#160;&#160;&#160; System.DateTime LastWriteTimeUtc {get;set;}     <br />Name&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; Property&#160;&#160;&#160;&#160;&#160;&#160; System.String Name {get;}     <br />Parent&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; Property&#160;&#160;&#160;&#160;&#160;&#160; System.IO.DirectoryInfo Parent {get;}     <br />Root&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; Property&#160;&#160;&#160;&#160;&#160;&#160; System.IO.DirectoryInfo Root {get;}     <br />BaseName&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; ScriptProperty System.Object BaseName {get=$this.Name;}</div>  <p>Well, that’s basically it. Enjoy!</p>  <p>/ Johan</p>]]></content:encoded>
    </item>
    <item>
      <title>System.Text.EncoderExceptionFallback</title>
      <link>https://docs.microsoft.com/archive/blogs/johan/system-text-encoderexceptionfallback</link>
      <pubDate>Thu, 01 Dec 2011 05:32:00 GMT</pubDate>
      <dc:creator><![CDATA[JohanSt]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/johan/2011/12/01/system-text-encoderexceptionfallback/</guid>
      <description><![CDATA[Today I found the following e-mail in my inbox:
Hello According to this article,...]]></description>
      <content:encoded><![CDATA[<p>Today I found the following e-mail in my inbox:</p>
<p><span style="color: #808080;"><em>Hello According to this article, <span style="color: #3366ff;"><a href="http://blogs.msdn.com/b/johan/archive/2008/01/31/using-windbg-hunting-exceptions.aspx"><span style="color: #3366ff;">http://blogs.msdn.com/b/johan/archive/2008/01/31/using-windbg-hunting-exceptions.aspx</span></a></span> written by you, you write that there are three "ever-present exceptions", I can see why they have to be on the heap, but why is 790ff624 3 36 System.Text.DecoderExceptionFallback 790ff5d8 3 36 System.Text.EncoderExceptionFallback Also always there? I always see them on the heep when I do a debug session. I have always discarded them. According to Tess, they are "not real exceptions", refering to that a print of all exceptions on the heap throws an error when the are printed. I think that the are put on the heap when the process is created, like the other three. But why? Why are they so important? I DEMAND an answer, because I love you and your blog :) I am just joking. I have written to you because I think that you know your ways around the CLR and the heap.</em></span></p>
<p>I thought the answer might interest others as well, so I decided to answer the e-mail here.</p>
<h1></h1>
<h1>This is not an Exception</h1>
<p>The reason why these are on the heap and are not possible to examine using !PrintException (!pe) is because they&rsquo;re actually not Exceptions at all. They show up when you run !dumpheap -type Exception because they contain the word &ldquo;Exception&rdquo; in their name, but that&rsquo;s it. The System.Text.DecoderExceptionFallback object for example derives from the DecoderFallback object. It&rsquo;s a fail-safe mechanism that is used when you can&rsquo;t class that is used then you can&rsquo;t complete the decoding conversion.</p>
<h2>So what is a Decoder Fallback?</h2>
<p>There are different fallbacks you can use. You can use the DecoderReplacementFallback that will replace any byte sequence that it can&rsquo;t decode with a predefined string. For example; the decoder comes across a segment it can&rsquo;t convert. You&rsquo;ve defined a DecoderReplacementFallback and it replaces the segment with &ldquo;[unknown]&rdquo;. Execution will then continue.</p>
<p>If you had instead defined a DecoderExceptionFallback a DecoderFallbackException (notice the difference?) would be thrown when the decoder came across the segment that it couldn&rsquo;t convert and execution would stop after that.</p>
<p>Cheers! / Johan</p>]]></content:encoded>
    </item>
    <item>
      <title>Changing Site Settings through code in SharePoint 2010</title>
      <link>https://docs.microsoft.com/archive/blogs/johan/changing-site-settings-through-code-in-sharepoint-2010</link>
      <pubDate>Tue, 13 Sep 2011 06:44:00 GMT</pubDate>
      <dc:creator><![CDATA[JohanSt]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/johan/2011/09/13/changing-site-settings-through-code-in-sharepoint-2010/</guid>
      <description><![CDATA[It&rsquo;s been quite a while since I had the time to post. A customer dropped me this question...]]></description>
      <content:encoded><![CDATA[<p>It&rsquo;s been quite a while since I had the time to post. A customer dropped me this question today and I thought it&rsquo;d be interesting to share.</p>
<p>He wanted to change the &ldquo;Allow rules to specify another site as a target location&rdquo;-setting (seen below) through code and needed to know if this could be done. <br />I hadn&rsquo;t tried this before, but thought it&rsquo;d be fun to try.</p>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/75/43/metablogapi/2210.Setting_7108B5AF.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-75-43-metablogapi/2210.Setting_5F00_7108B5AF.png"><img style="background-image: none; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px; border: 0px;" title="Setting" border="0" alt="Setting" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/75/43/metablogapi/8547.Setting_thumb_6185A3E0.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-75-43-metablogapi/8547.Setting_5F00_thumb_5F00_6185A3E0.png" width="703" height="388" /></a></p>
<h2>Finding the correct key</h2>
<p>I suspected that the property could be found in Web.AllProperties, but I had no clue as to what the key might be called, so I simply iterated through all the keys twice. First with the setting enabled and secondly with the setting disabled. I wrote the keys to a label, and simply pasted them into Notepad so I could compare the two listings. The code I used to do this was quite simple:</p>
<pre>foreach (String key in Web.AllProperties.Keys)
{&nbsp;&nbsp;&nbsp;&nbsp; lblKeys.Text += key + "&lt;BR&gt;";
}</pre>
<p>Having done this it was quite easy to identify the key I needed. It turned out it was called &ldquo;_routerenablecrosssiterouting&rdquo;. I recommend using the same approach if there is another setting you wish to change.</p>
<h2>The final code</h2>
<p>Now that I had the key name I was basically done. I used the following line to read the setting:</p>
<pre>myString = (Web.AllProperties["_routerenablecrosssiterouting"]).ToString();</pre>
<p>This is the code I used to change it:</p>
<pre>Web.AllowUnsafeUpdates = true;
Web.AllProperties["_routerenablecrosssiterouting"] = "False";
Web.Update();</pre>
<p>Since I was using a GET-request in my little sample I had to set AllowUnsafeUpdates = true</p>
<p>I&rsquo;ve seen other people asking how to accomplish this on the net, so hopefully this post will be of use to you.</p>
<p>/ Johan</p>]]></content:encoded>
    </item>
    <item>
      <title>Problems running sos-commands</title>
      <link>https://docs.microsoft.com/archive/blogs/johan/problems-running-sos-commands</link>
      <pubDate>Fri, 04 Mar 2011 02:04:00 GMT</pubDate>
      <dc:creator><![CDATA[JohanSt]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/johan/2011/03/04/problems-running-sos-commands/</guid>
      <description><![CDATA[Yesterday I tried opening up a standard dump file from a 64-bit Windows 2008 Server. It opened up...]]></description>
      <content:encoded><![CDATA[<p>Yesterday I tried opening up a standard dump file from a 64-bit Windows 2008 Server. It opened up just fine in windbg, but when I tried executing a command I got the following:</p>
<div class="SampleCode">
<pre>0:000&gt; !dumpheap -stat
The garbage collector data structures are not in a valid state for traversal.
It is either in the "plan phase," where objects are being moved around, or
we are at the initialization or shutdown of the gc heap. Commands related to 
displaying, finding or traversing objects as well as gc heap segments may not 
work properly. !dumpheap and !verifyheap may incorrectly complain of heap 
consistency errors.
Error requesting GC Heap data
Unable to build snapshot of the garbage collector state</pre>
</div>
<p>This can happen if both the .NET 4.0 and the .NET 2.0 runtime are loaded in the same process. I actually tried using .loadby on both Framework versions and neither of them returned with an error</p>
<div class="SampleCode">
<pre>0:000&gt; .loadby sos mscorwks
0:000&gt; .loadby sos clr</pre>
</div>
<p>The easiest way to resolve this is to run the following command:</p>
<div class="SampleCode">
<pre>0:000&gt; .cordll -I mscorwks.dll -N -ve</pre>
</div>
<p>After that, simply reload the extensions you want to use and you should be fine.</p>]]></content:encoded>
    </item>
    <item>
      <title>Updating the Smart tag panel of a WebControl requires closing and reopening the panel</title>
      <link>https://docs.microsoft.com/archive/blogs/johan/updating-the-smart-tag-panel-of-a-webcontrol-requires-closing-and-reopening-the-panel</link>
      <pubDate>Thu, 02 Sep 2010 01:23:00 GMT</pubDate>
      <dc:creator><![CDATA[JohanSt]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/johan/2010/09/02/updating-the-smart-tag-panel-of-a-webcontrol-requires-closing-and-reopening-the-panel/</guid>
      <description><![CDATA[The problem
I came across the following scenario a while back: A customer was creating a custom...]]></description>
      <content:encoded><![CDATA[<h1></h1>
<h1>The problem</h1>
<p>I came across the following scenario a while back: A customer was creating a custom WebControl in the Visual Web Designer. The control had a smart tag panel with an option that they wanted to behave like a radio button. I.e. The text says &ldquo;Enabled&rdquo;, you click it and it changes to &ldquo;Disabled&rdquo;. The problem was that the panel didn&rsquo;t refresh. Even if they called DesignerActionUIService.Refresh(). They had to close the panel and reopen it for the change to become visible.</p>
<p>If they instead hosted the same code in a WinForms control then the panel was refreshed immediately. So in effect the code below would update immediately if designing a WinForms component, and require closing and reopening the panel if designing a WebForms panel.</p>
<div class="SampleCode">
<pre>public bool LockColors
{
    get
    {
        return colLabel.ColorLocked;
    }
    set
    {
        GetPropertyByName("ColorLocked").SetValue(colLabel, value);

        // Refresh the list.
        this.designerActionUISvc.Refresh(this.Component);
    }
}</pre>
</div>
<h1>Cause</h1>
<p>Simply put, the Web Developer doesn&rsquo;t subscribe to the DesignerActionUIStateChange event, so this is currently by design.</p>
<h1>Resolution</h1>
<p>You can fix this by implementing your own event using code like this:</p>
<div class="SampleCode">
<pre>public UserControlDesignerActionList(ISourceControlledItem scItem)
        : base(((IDesigner)scItem).Component)
    {
        this.designerActionUISvc = GetService(typeof(DesignerActionUIService))
as DesignerActionUIService;
 
        if (this.Component is Control) {
            this.designerActionUISvc.DesignerActionUIStateChange += 
new DesignerActionUIStateChangeEventHandler(OnDesignerActionUIStateChange);
        }
    }
 
    void OnDesignerActionUIStateChange(object sender, DesignerActionUIStateChangeEventArgs e) {
        if (e.ChangeType == DesignerActionUIStateChangeType.Refresh) {
            ElementDesigner ed = ElementDesigner.GetElementDesigner((Control)this.Component);
            IWebElementDesigner wed = (IWebElementDesigner)ed;
            if (wed != null) {
                wed.UpdateView();
            }
        }
    }</pre>
</div>
<p>In order for this to work you need to add a reference to Microsoft.Web.Design.Client.dll, which is located at C:\Program Files (x86)\Microsoft Visual Studio 9.0\Common7\IDE\Microsoft.Web.Design.Client.dll as well as in the Global Assembly Cache.</p>
<h1>Licensing</h1>
<p>The main issue with this approach is that of licencing. If you intend to redistribute this component to a customer you may redistribute the .dll to that customer if they already own a valid license of that same .dll. Any component you design that need this change to work would require a copy of Visual Studio to be at all usefull, but you never know...</p>
<p>The best approach would probably be to rely on the version in the GAC and not distribute the .dll at all.</p>]]></content:encoded>
    </item>
    <item>
      <title>Using SSL without an Internet connection</title>
      <link>https://docs.microsoft.com/archive/blogs/johan/using-ssl-without-an-internet-connection</link>
      <pubDate>Tue, 02 Feb 2010 04:39:14 GMT</pubDate>
      <dc:creator><![CDATA[JohanSt]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/johan/2010/02/02/using-ssl-without-an-internet-connection/</guid>
      <description><![CDATA[Problem  If you have a web application that uses SSL and this application, for some reason, is...]]></description>
      <content:encoded><![CDATA[<h1>Problem</h1>  <p>If you have a web application that uses SSL and this application, for some reason, is hosted on an IIS that doesn’t have Internet access you will eventually find that any call to the server over SSL will take a lot of time to reply. It doesn’t matter if it’s ASP.NET, classic ASP or even CSS. As long as the request is made via SSL the response-time will skyrocket.</p>  <p>This isn’t a very common situation, since normally the IIS is connected to the Internet. HoweverI’ve come across this “in the field” where clients were routed internally to the IIS through a proxy, so it <em>does</em> happen.</p>  <h1>Cause</h1>  <p>This is a variation of the problem described in <a href="http://blogs.msdn.com/johan/archive/2009/11/12/make-sure-you-have-an-internet-connection-when-using-signed-assemblies.aspx">this</a> article. The IIS will want to go on-line and verify that the certificate has not been revoked. In order to do this is requires a working Internet connection. Otherwise it will wait until the request times out and then service the request. When the next SSL-request comes along it will attempt to go on-line again, time out, and so on.</p>  <p>If you've had your server connected to the Internet during testing, then you will most likely not come across this problem straight away, since the response from the lookup in the certificate revocation list (CRL) will be cached. This makes it harder to pinpoint the root cause, unless you know where to look.</p>  <h1>Resolution</h1>  <p>The easiest way to resolve this is to skip CRL checking. This is done by setting the metabase property <a href="http://www.microsoft.com/technet/prodtechnol/WindowsServer2003/Library/IIS/0c08d268-1634-4486-8382-b735e295b3aa.mspx?mfr=true">CertCheckMode</a> to 1.</p>  <p>Create a blank .txt file on the server and paste the following code into it:</p>  <div class="SampleCode">   <pre>Set oWeb = GetObject(&quot;IIS://localhost/W3SVC&quot;)
oWeb.CertCheckMode = 1
oWeb.SetInfo
Set oWeb = Nothing</pre>
</div>

<p>Running this script will change the property so that revocation checking is no longer done. If you want to switch back to the default value, then you should set CertCheckMode to 0 instead.</p>

<p>/ Johan</p>]]></content:encoded>
    </item>
    <item>
      <title>Make sure you have an Internet connection when using signed assemblies</title>
      <link>https://docs.microsoft.com/archive/blogs/johan/make-sure-you-have-an-internet-connection-when-using-signed-assemblies</link>
      <pubDate>Thu, 12 Nov 2009 03:08:22 GMT</pubDate>
      <dc:creator><![CDATA[JohanSt]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/johan/2009/11/12/make-sure-you-have-an-internet-connection-when-using-signed-assemblies/</guid>
      <description><![CDATA[A customer called in the other day and told me that his web application took a long time to start....]]></description>
      <content:encoded><![CDATA[<p>A customer called in the other day and told me that his web application took a long time to start. My initial thought was (off course) that it was a matter of the classic slow-to start web services I’ve written about earlier.</p>  <p>(<a title="What to do about the slow startup of web services" href="http://blogs.msdn.com/johan/archive/2008/04/02/what-to-do-about-the-slow-startup-of-web-services.aspx">What to do about the slow startup of web services</a>)</p>  <p>As I learned more about his problem I found that this was more than just a simple matter of pre-compilation and keeping your w3wp.exe alive.</p>  <h1>The Cause</h1>  <p>The customer was using authenticode signed assemblies in his web application. When that application calls the assembly for the first time it will want to go on-line and check that the certificate is still valid. So, what if this is an internal server with no Internet access? Well, then we have a problem. The process will spend quite some time trying to check the certificate revocation lists. Eventually it will give up, but for my customer this meant that it hung for at least 20 seconds upon startup.</p>  <h1>The Resolution</h1>  <p>To resolve this I’d chose one of the following three options:</p>  <h3>Grant Internet access to the server</h3>  <p>This is will obviously resolve the problem, but may not always be possible.</p>  <h3>Review the need for Authenticode signing</h3>  <p>If you own the assemblies then you might want to consider not using Authenticode signing at all. A Strong Named Assembly might be sufficient. For more information on Strong Named Assemblies and how to create them, please see the following article on MSDN: <a title="How to- Sign an Assembly with a Strong Name" href="http://msdn.microsoft.com/en-us/library/xc31ft41.aspx" target="_blank">How to: Sign an Assembly with a Strong Name</a></p>  <h3>Disable Signature Verification</h3>  <p>If all else fails you can disable Signature Verification by adding the following to your machine.config or application.exe.config:</p>  <div class="SampleCode">&lt;configuration&gt;    <br />&#160;&#160;&#160;&#160; &lt;runtime&gt;     <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; &lt;generatepublisherevidence enabled=&quot;false&quot; /&gt;     <br />&#160;&#160;&#160;&#160; &lt;/runtime&gt;     <br />&lt;/configuration&gt; </div>  <p></p>  <h1>Identifying the problem using windbg</h1>  <p>Okay, so if we suspect that this is the problem, how can we verify this?</p>  <p>I got a memory dump from my customer, so I’ll use that to demonstrate.</p>  <p>First of all you want to make sure the dump is taken as the application pool hangs upon the first request. Getting a dump right after the problem has occurred will usually do us no good at all. We need to get the dump as the problem is actually ocurring. Having made sure the dump is fine I open up the dump in windbg and load sos.dll. I then use the !aspxpages command to see the pending requests currently on the server. !aspxpages dumps all the HttpContexts found on the heap so we get a list of all currently executing requests, as well as recently finished ones that haven’t been garbage collected yet.</p>  <div class="DebugSample">0:000&gt; .load C:\Windows\Microsoft.NET\Framework\v2.0.50727\sos.dll    <br />0:000&gt; !aspxpages     <br />Going to dump the HttpContexts found in the heap.     <br />Loading the heap objects into our cache.     <br />HttpContext&#160;&#160;&#160; Timeout&#160; Completed&#160;&#160;&#160;&#160; Running&#160; ThreadId ReturnCode&#160;&#160; Verb RequestPath+QueryString     <br />0x01b41ad4&#160;&#160;&#160;&#160;&#160;&#160;&#160; 0&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; no&#160;&#160;&#160;&#160;&#160;&#160;&#160; 11 Sec&#160;&#160;&#160;&#160; XXX&#160;&#160;&#160;&#160;&#160;&#160;&#160; 200&#160;&#160;&#160;&#160;&#160;&#160; /App/     <br />0x01b75f48&#160;&#160;&#160;&#160;&#160; 110 Sec&#160;&#160;&#160;&#160;&#160;&#160;&#160; no&#160;&#160;&#160;&#160;&#160;&#160;&#160; 11 Sec&#160;&#160;&#160;&#160; XXX&#160;&#160;&#160;&#160;&#160;&#160;&#160; 401&#160;&#160; GET /App/Default.aspx     <br />0x01b7eb40&#160;&#160;&#160; 19200 Sec&#160;&#160;&#160;&#160;&#160;&#160;&#160; no&#160;&#160;&#160;&#160;&#160;&#160;&#160; 11 Sec&#160;&#160;&#160;&#160;&#160; <font color="#ff0000">19</font>&#160;&#160;&#160;&#160;&#160;&#160;&#160; 200&#160;&#160; GET /App/Default.aspx     <br />Total 3 HttpContext objects </div>  <p>So, the request on thread 19 is the one we want. As we can see in the ThreadId column it is the only active request. Let’s jump to that thread and investigate what it is doing.</p>  <div class="DebugSample">0:000&gt; ~19s    <br />eax=01510000 ebx=00000000 ecx=03e2d348 edx=776d9a94 esi=03e2d07c edi=00000000     <br />eip=776d9a94 esp=03e2d034 ebp=03e2d0a4 iopl=0&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; nv up ei ng nz ac pe cy     <br />cs=001b&#160; ss=0023&#160; ds=0023&#160; es=0023&#160; fs=003b&#160; gs=0000&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; efl=00000297     <br />ntdll!KiFastSystemCallRet:     <br />776d9a94 c3&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; ret     <br />0:019&gt; !clrstack     <br />OS Thread Id: 0x11cc (19)     <br />ESP&#160;&#160;&#160;&#160;&#160;&#160; EIP&#160;&#160;&#160;&#160; <br />03e2eb8c 776d9a94 [PrestubMethodFrame: 03e2eb8c] App.BasePage.<font color="#ff0000">Page_Load</font>(System.Object, System.EventArgs)     <br />03e2eba0 6aada7ff System.Web.Util.CalliHelper.EventArgFunctionCaller(IntPtr, System.Object, System.Object, System.EventArgs)     <br />03e2ebb0 6c392594 System.Web.Util.CalliEventHandlerDelegateProxy.Callback(System.Object, System.EventArgs)     <br />03e2ebc4 6c38ba84 System.Web.UI.Control.OnLoad(System.EventArgs)     <br />03e2ebd8 6c38bac3 System.Web.UI.Control.LoadRecursive()     <br />03e2ebf0 6c387b74 System.Web.UI.Page.ProcessRequestMain(Boolean, Boolean)     <br />03e2ed48 6c3877a4 System.Web.UI.Page.ProcessRequest(Boolean, Boolean)     <br />03e2ed80 6c3876d1 System.Web.UI.Page.ProcessRequest()     <br />03e2edb8 6c387666 System.Web.UI.Page.ProcessRequestWithNoAssert(System.Web.HttpContext)     <br />03e2edc4 6c387642 System.Web.UI.Page.ProcessRequest(System.Web.HttpContext)     <br />03e2edd8 012b02a6 ASP.text.ProcessRequest(System.Web.HttpContext)     <br />03e2ede8 6c38db16 System.Web.HttpApplication+CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute()     <br />03e2ee1c 6c36132c System.Web.HttpApplication.ExecuteStep(IExecutionStep, Boolean ByRef)     <br />03e2ee5c 6c95531f System.Web.HttpApplication+PipelineStepManager.ResumeSteps(System.Exception)     <br />03e2ee60 6c94b704 [InlinedCallFrame: 03e2ee60]     <br />03e2ef00 6c93613d System.Web.HttpRuntime.ProcessRequestNotificationPrivate(System.Web.Hosting.IIS7WorkerRequest, System.Web.HttpContext)     <br />03e2ef70 6ca0a7a2 System.Web.Hosting.PipelineRuntime.ProcessRequestNotificationHelper(IntPtr, IntPtr, IntPtr, Int32)     <br />03e2ef74 6ca0a58f [InlinedCallFrame: 03e2ef74]     <br />03e2f4c8 01092314 [NDirectMethodFrameStandalone: 03e2f4c8] System.Web.Hosting.UnsafeIISMethods.MgdIndicateCompletion(IntPtr, System.Web.RequestNotificationStatus ByRef)     <br />03e2f4d8 6ca0a839 System.Web.Hosting.PipelineRuntime.ProcessRequestNotificationHelper(IntPtr, IntPtr, IntPtr, Int32)     <br />03e2f55c 6ca0a58f System.Web.Hosting.PipelineRuntime.ProcessRequestNotification(IntPtr, IntPtr, IntPtr, Int32)     <br />03e2f65c 01092314 [ContextTransitionFrame: 03e2f65c] </div>  <p>So we’re in the Page_Load event of the page in question, but apart from that !clrstack doesn’t tell us much. Let’s take a look at the native callstack instead using the kb-command.</p>  <div class="DebugSample">0:019&gt; kb20    <br />ChildEBP RetAddr&#160; Args to Child&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <br />03e2d030 776d9254 76adc244 000006d8 00000000 ntdll!KiFastSystemCallRet     <br />03e2d034 76adc244 000006d8 00000000 03e2d07c ntdll!ZwWaitForSingleObject+0xc     <br />03e2d0a4 74256247 000006d8 00003a98 00000000 kernel32!<font color="#ff0000">WaitForSingleObjectEx</font>+0xbe     <br />03e2d0d8 74251f7c 0141f2e4 00000002 00202005 cryptnet!CryptRetrieveObjectByUrlWithTimeout+0x1a5     <br />03e2d1c8 742527a1 0141f2e4 00000002 00202005 cryptnet!CryptRetrieveObjectByUrlW+0xcc     <br />03e2d268 742591be 00000000 0141f2e4 00000002 cryptnet!RetrieveObjectByUrlValidForSubject+0xa0     <br />03e2d2c8 74252556 00000000 00000000 00000001 cryptnet!RetrieveTimeValidObjectByUrl+0x15c     <br />03e2d374 74253fc1 00000082 0141f2d8 00000000 cryptnet!CTVOAgent::GetTimeValidObjectByUrl+0x178     <br />03e2d45c 74253d98 00000003 018aa590 00000002 cryptnet!CTVOAgent::GetTimeValidObject+0x4a8     <br />03e2d48c 74253428 00000003 018aa590 018c8220 cryptnet!FreshestCrlFromCrlGetTimeValidObject+0x2d     <br />03e2d4d0 74259283 00000003 018aa590 018c8220 cryptnet!CryptGetTimeValidObject+0x58     <br />03e2d54c 74253b1c 00000003 018aa590 018aa590 cryptnet!GetTimeValidCrl+0x2cb     <br />03e2d590 74253992 018aa590 018c8220 03e2d5c8 cryptnet!GetBaseCrl+0x34     <br />03e2d63c 757f77d5 00000001 00000001 00000001 cryptnet!<font color="#ff0000">MicrosoftCertDllVerifyRevocation</font>+0x163     <br />03e2d6c8 757f7641 00000001 00000001 00000001 crypt32!I_CryptRemainingMilliseconds+0x2aa     <br />03e2d74c 757f7a26 00000001 00000001 00000001 crypt32!CertVerifyRevocation+0xd4     <br />03e2d7f8 757f7838 01899590 00000000 00000000 crypt32!CChainPathObject::CalculateRevocationStatus+0x2d0     <br />03e2d83c 75806c44 01899590 018c3018 01870fc0 crypt32!CChainPathObject::CalculateAdditionalStatus+0x152     <br />03e2d904 758069a5 01899590 018aa590 01870fc0 crypt32!CCertChainEngine::CreateChainContextFromPathGraph+0x23e     <br />03e2d93c 7580be14 018aa590 018aff94 01870fc0 crypt32!CCertChainEngine::GetChainContext+0x46     <br />03e2d974 749172ba 01421338 018aa590 018aff94 crypt32!CertGetCertificateChain+0x72     <br />03e2d9dc 749170fc 40000001 00000000 03e2da10 wintrust!_WalkChain+0x1ae     <br />03e2da18 7491363b 00000000 03e2dbdc 03e2db74 wintrust!WintrustCertificateTrust+0xb9     <br />03e2db30 7491346c 00000000 03e2dbe4 00000000 wintrust!_VerifyTrust+0x253     <br />03e2db54 64025b1b 00000000 03e2dbe4 03e2db74 wintrust!WinVerifyTrust+0x50     <br />03e2dbf8 716b7f4d <font color="#ff0000">014443f8</font> 00000000 00000003 mscorsec!<font color="#ff0000">GetPublisher</font>+0xe4     <br />03e2dc50 7145ed3b d60caabc 0188c4a8 00603c48 mscorwks!PEFile::CheckSecurity+0xcb     <br />03e2dc78 7145ec84 d60caa64 00000000 0188c4a8 mscorwks!PEAssembly::DoLoadSignatureChecks+0x3a     <br />03e2dca0 7145f0ca 01879f00 00000000 0188c4a8 mscorwks!PEAssembly::PEAssembly+0x109     <br />03e2df3c 7145f1c5 0188c4a8 00000000 00000000 mscorwks!PEAssembly::DoOpen+0x103     <br />03e2dfd0 71459062 0188c4a8 00000000 00000000 mscorwks!PEAssembly::Open+0x79     <br />03e2e134 71456ace 03e2e15c 00000001 00000000 mscorwks!AppDomain::BindAssemblySpec+0x247 </div>  <p>Here we see that we’re currently trying to check the certificate revocation list. This is done on a separate thread so this thread is currently doing nothing but waiting. Our next step would be to find this thread, but first we can find out the name of the .dll that we’re trying to verify. Look at the first argument to GetPublisher.</p>  <div class="DebugSample">0:019&gt; du <font color="#ff0000">014443f8</font>     <br />014443f8&#160; &quot;C:\Windows\Microsoft.NET\Framewo&quot;     <br />01444438&#160; &quot;rk\v2.0.50727\Temporary ASP.NET &quot;     <br />01444478&#160; &quot;Files\scstt\57ae16cd\2f8637d5\as&quot;     <br />014444b8&#160; &quot;sembly\dl3\078f3d05\00fba208_c03&quot;     <br />014444f8&#160; &quot;6ca01\Microsoft.Practices.Enterp&quot;     <br />01444538&#160; &quot;riseLibrary.Logging.DLL&quot; </div>  <p>So it’s a Microsoft .dll that is part of the Enterprise Library. Good to know. Now let’s find the thread that is attempting to retrieve the revocation list by running ~*kb and scanning through the threads until we find this one:</p>  <div class="DebugSample">0:021&gt; kb2000    <br />ChildEBP RetAddr&#160; Args to Child&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <br />0427d7f8 776d9254 75502283 0000070c 00000001 ntdll!KiFastSystemCallRet     <br />0427d7fc 75502283 0000070c 00000001 0427d824 ntdll!ZwWaitForSingleObject+0xc     <br />0427d83c 75501fc8 0000070c 00000714 00000001 mswsock!SockWaitForSingleObject+0x19f     <br />0427d928 77801693 00000001 00000000 0427d9d0 mswsock!WSPSelect+0x38c     <br />0427d9a8 72a733e5 00000001 00000000 0427d9d0 ws2_32!select+0x494     <br />0427e1ec 72a730fd 00000714 0427e210 72a72e88 winhttp!ICSocket::Connect_Start+0x3b0     <br />0427e1f8 72a72e88 01828250 72a737bc 00000000 winhttp!CFsm_SocketConnect::RunSM+0x42     <br />0427e210 72a7382b 018b0c60 00000000 00000000 winhttp!CFsm::Run+0x20     <br />0427e234 72a7467d 01828250 018ccf30 0427e258 winhttp!DoFsm+0x2a     <br />0427e244 72a74646 0000ea60 00000005 00000020 winhttp!ICSocket::Connect+0x32     <br />0427e258 72a742b5 0000ea60 00000005 0000ea60 winhttp!ICSocket::Connect+0x13     <br />0427e2a4 72a74038 01434458 0427e2c8 72a72e88 winhttp!HTTP_REQUEST_HANDLE_OBJECT::OpenConnection_Fsm+0x471     <br />0427e2b0 72a72e88 01434458 00000000 00000000 winhttp!CFsm_OpenConnection::RunSM+0x37     <br />0427e2c8 72a7382b 018b0c60 00000000 00000000 winhttp!CFsm::Run+0x20     <br />0427e2ec 72a74625 01434458 018ccf30 0427e324 winhttp!DoFsm+0x2a     <br />0427e2fc 72a745bc 00000000 00000000 018b0c60 winhttp!HTTP_REQUEST_HANDLE_OBJECT::OpenConnection+0x2f     <br />0427e324 72a74526 0141f638 0427e348 72a72e88 winhttp!HTTP_REQUEST_HANDLE_OBJECT::MakeConnection_Fsm+0x9b     <br />0427e330 72a72e88 0141f638 00000000 00000000 winhttp!CFsm_MakeConnection::RunSM+0x37     <br />0427e348 72a7382b 018b0c60 00000000 00000000 winhttp!CFsm::Run+0x20     <br />0427e36c 72a743c1 0141f638 018b0c60 014343c0 winhttp!DoFsm+0x2a     <br />0427e3ac 72a74339 014343c0 0427e3d0 72a72e88 winhttp!HTTP_REQUEST_HANDLE_OBJECT::SendRequest_Fsm+0x93     <br />0427e3b8 72a72e88 014343c0 018ccf30 00000000 winhttp!CFsm_SendRequest::RunSM+0x37     <br />0427e3d0 72a7382b 018b0c60 00000000 00000000 winhttp!CFsm::Run+0x20     <br />0427e3f4 72a73db0 014343c0 018b0c60 01888820 winhttp!DoFsm+0x2a     <br />0427e414 72a76f71 00000000 0427e438 72a72e88 winhttp!HTTP_REQUEST_HANDLE_OBJECT::HttpSendRequest_Start+0x2af     <br />0427e420 72a72e88 01888820 00000001 00000000 winhttp!CFsm_HttpSendRequest::RunSM+0x4c     <br />0427e438 72a73c3e 018b0c60 00000000 00000000 winhttp!CFsm::Run+0x20     <br />0427e480 72a73b8b 01888820 018ccf30 00000000 winhttp!StartFsmChain+0xcf     <br />0427e4c4 72a739d8 018ccf30 00000000 00000000 winhttp!HttpWrapSendRequest+0x18c     <br />0427e544 742599b4 018ccf30 00000000 00000000 winhttp!WinHttpSendRequest+0x19b     <br />0427f5e4 74259741 005f7bc0 018ccf30 01898e60 cryptnet!InetSendAuthenticatedRequestAndReceiveResponse+0x56f     <br />0427f6ec 7425921d 005f7bc0 <font color="#ff0000">01898e60</font> 00202005 cryptnet!InetSendReceiveUrlRequest+0x2c8     <br />0427f724 742523e9 <font color="#ff0000">01898e60</font> 00000002 00202005 cryptnet!CInetSynchronousRetriever::RetrieveObjectByUrl+0x5f     <br />0427f75c 742521a8 <font color="#ff0000">01898e60</font> 00000002 00202005 cryptnet!InetRetrieveEncodedObject+0x64     <br />0427f7b8 74256350 <font color="#ff0000">01898e60</font> 00000002 00202005 cryptnet!CObjectRetrievalManager::RetrieveObjectByUrl+0xbb     <br />0427f810 76ad4911 00000000 0427f85c 776be4b6 cryptnet!CryptRetrieveObjectByUrlWithTimeoutThreadProc+0x67     <br />0427f81c 776be4b6 01898db0 4e080acf 00000000 kernel32!BaseThreadInitThunk+0xe     <br />0427f85c 776be489 742562f7 01898db0 ffffffff ntdll!__RtlUserThreadStart+0x23     <br />0427f874 00000000 742562f7 01898db0 00000000 ntdll!_RtlUserThreadStart+0x1b     <br />0:021&gt; du <font color="#ff0000">01898e60</font>     <br />01898e60&#160; &quot;http://crl.microsoft.com/pki/crl&quot;     <br />01898ea0&#160; &quot;/products/CodeSignPCA2.crl&quot; </div>  <p>This is the thread. To finally verify that it is in fact attempting to download the Certificate Revocation List we can check the value of the first argument to cryptnet!CInetSynchronousRetriever, InetRetrieveEncodedObject and CObjectRetrievalManager::RetrieveObjectByUrl or the second argument to cryptnet!InetSendReceiveUrlRequest as I did above.</p>  <h1>Conclusion</h1>  <p>In this case the customer chose to disable Signature Verification completely rather than granting Internet access to the server.</p>  <p>If you found the windbg-portion of this post hard to understand I can recommend a closer look at my Debugging School (In the menu to the left). Begin with <a title="Getting started with windbg - Part I" href="http://blogs.msdn.com/johan/archive/2007/11/13/getting-started-with-windbg-part-i.aspx">Getting started with windbg - Part I</a> and you should be set to go in no time.</p>  <p>/ Johan</p>]]></content:encoded>
    </item>
    <item>
      <title>Investigating Locks</title>
      <link>https://docs.microsoft.com/archive/blogs/johan/investigating-locks</link>
      <pubDate>Fri, 09 Oct 2009 09:49:56 GMT</pubDate>
      <dc:creator><![CDATA[JohanSt]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/johan/2009/10/09/investigating-locks/</guid>
      <description><![CDATA[Consider the following scenario:  You have an ASP.NET application which intermittently responds...]]></description>
      <content:encoded><![CDATA[<p>Consider the following scenario:</p>  <p>You have an ASP.NET application which intermittently responds sluggishly. As the problem occurs memory usage is about average, as is CPU usage, but still certain pages respond slower and slower. The machine acts just as if it is under heavy load, but judging from the CPU it isn't. In fact CPU usage might even <em>decrease</em> rather than increase. When trying to access non .NET content such as plain text/html or images you usually find that response times are just as fast as ever.</p>  <p>When you find that your application has hung in a low CPU state it is usually because of one of the following reasons (in order of likelihood based on my experience) :</p>  <ol>   <li>External resources responding slowly. E.g. a database query or AD lookup is taking a long time to complete and so the application is simply waiting for another server to respond. </li>    <li>One of the threads of the application has entered a critical section and now several other threads are waiting to enter the same critical section. </li>    <li>A classic deadlock. Thread A waits for thread B which waits for thread C which waits for thread A. </li> </ol>  <p>Quite often you'll see a mixture of items 1 and 2. A thread enters a critical section, calls a remote database, or similar, and all other threads attempting to enter the same critical section will have to nicely stay in line until the struggling database has responded. Still, it is quite possible that the critical section is waiting for a local event to finish, but then you'd usually see a higher CPU load on the machine. (Though not necessarily in the w3wp.exe process.)</p>  <h1>What are Critical Sections?</h1>  <p>In case you've forgotten or simply not worked that much with critical sections it might be necessary to refresh your memory on this.</p>  <p>A Critical Section is a segment of code that you do not want to be executed more than one at a time. In order to ensure this you use the <strong>lock</strong> keyword to ensure that a certain block of code is able to complete with no interruption from any other threads. To illustrate this I've created the following code sample:</p>  <div class="SampleCode">   <pre>public class FileIO
{
    private static object myLock = new object();

	public FileIO()
	{
	}

    public string performLockOperation()
    {
        string strResult = &quot;The Lock Operation started on &quot; + System.DateTime.Now.ToLongTimeString();
        lock (myLock)
        {
            // Let the thread sleep for 10 seconds
            // This way we simulate a File IO operation that takes some time to complete.
            System.Threading.Thread.Sleep(10000);
        }
        strResult += &quot; and ended on &quot; + System.DateTime.Now.ToLongTimeString();
        return strResult;
    }

    public string performNoLockOperation()
    {
        string strResult = &quot;The No Lock Operation started on &quot; + System.DateTime.Now.ToLongTimeString();
        System.Threading.Thread.Sleep(10000);
        strResult += &quot; and ended on &quot; + System.DateTime.Now.ToLongTimeString();
        return strResult;
    }

}</pre>
</div>

<p>Let's take a quick look at the parts of this class that I've written, called FileIO:</p>

<h2></h2>

<h2>myLock</h2>

<p>The class has a static variable called myLock that I will be using to identify the lock I'm about to create. This is why the variable is static. Otherwise I'd be creating new locks for each instance of the FileIO class leaving the lock operation completely redundant. Now that I use a static variable the lock spans all instances of the FileIO class.</p>

<h2>constructor</h2>

<p>The constructor is empty. Move along. Nothing to see here.</p>

<h2>performLockOperation</h2>

<p>This is the most interesting part of the class. It is the function we'll be using to actually reproduce the potential problems. The function returns a string which will contain information about when the call to the function was made and when it completed. We store this data in a string called strResult which we will eventually be returning as the result of the function call.</p>

<p>Having declared this variable and put the initial time of the function call in it we then create our lock. This is simply done with the following syntax:</p>

<div class="SampleCode">
  <pre>lock (object)
{
}</pre>
</div>

<p>Any code within this block will first make sure that there is not already a lock taken on this object. If there is, then they will pause execution and wait for the lock to become available before continuing execution.</p>

<p>Inside our lock we then simulate a slow File IO operation by letting the thread sleep for 10 seconds.</p>

<p>After that we append the current time to the result and return it.</p>

<h2>performNoLockOperation</h2>

<p>This function is identical to the previous one, except this time we do not have a critical section. This function is included just for comparison.</p>

<h1>The potential problem</h1>

<p>Now, let's get down to business. If we have a web page that makes a call to the performLockOperation-function and that page is requested at the same time by four different clients. What would be the response times?</p>

<p>The answer is 10, 20, 30 &amp; 40 seconds.</p>

<p>Here's why:</p>

<ol>
  <li>The thread handling the first request enters the critical section, effectively locking it for everyone else. When it is complete 10 seconds have passed due to the Sleep-call. </li>

  <li>One of the other threads enters the critical section once the first request is finished. It has already waited for 10 seconds, and the thread will now sleep for an additional 10 seconds. </li>

  <li>As the second thread finishes one of the remaining two enters the critical section. It has now waited for 20 seconds and will sleep for an additional 10. </li>

  <li>The final request is able to enter the critical section after having waited for 30 seconds. Once it is complete 40 seconds have passed. </li>
</ol>

<p>If we'd been using the performNoLockOperation instead then all requests would have responded after 10 seconds.</p>

<p>Now, I know that 10 seconds is an exceptionally long time to let the thread sleep, but this was all for illustration purposes. Imagine instead that the sleeping time was 1 second and the number of requests was 200...</p>

<h1></h1>

<h1>Troubleshooting this issue</h1>

<p>Okay, so what would it look like when this problem occurs? Let's have a look. If you haven't looked at my posts on getting started with Windbg, then I suggest reading them before continuing. (<a href="http://blogs.msdn.com/johan/archive/2007/11/13/getting-started-with-windbg-part-i.aspx">Part I</a> &amp; <a href="http://blogs.msdn.com/johan/archive/2008/05/28/powershell-an-introduction-part-ii.aspx">Part II</a>)</p>

<p>First of all I fire up WinDbg, then I attach to the w3wp.exe. I then use &quot;~*e!clrstack&quot; to look at the managed threads of the w3wp.exe application. Here is a snippet of what I get:</p>

<div class="DebugSample">
  <pre>OS Thread Id: 0xce0 (24)
Child-SP         RetAddr          Call Site
000000000447e0f0 000007ff001e13d2 FileIO.performLockOperation()
000000000447e170 000007feee323ec9 _Default.Page_Load(System.Object, System.EventArgs)
000000000447e1b0 000007fee7956aea System.Web.Util.CalliHelper.EventArgFunctionCaller(IntPtr, System.Object, System.Object, System.EventArgs)
000000000447e1e0 000007fee794d2c4 System.Web.Util.CalliEventHandlerDelegateProxy.Callback(System.Object, System.EventArgs)
000000000447e210 000007fee794d322 System.Web.UI.Control.OnLoad(System.EventArgs)
000000000447e250 000007fee79498ac System.Web.UI.Control.LoadRecursive()
000000000447e2a0 000007fee7948db0 System.Web.UI.Page.ProcessRequestMain(Boolean, Boolean)
000000000447e370 000007fee7948cdb System.Web.UI.Page.ProcessRequest(Boolean, Boolean)
000000000447e3d0 000007fee7948c70 System.Web.UI.Page.ProcessRequest()
000000000447e430 000007ff001e0c09 System.Web.UI.Page.ProcessRequest(System.Web.HttpContext)
000000000447e490 000007fee7950117 ASP.default_aspx.ProcessRequest(System.Web.HttpContext)
000000000447e4c0 000007fee791449b System.Web.HttpApplication+CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute()
000000000447e570 000007fee7ffbd41 System.Web.HttpApplication.ExecuteStep(IExecutionStep, Boolean ByRef)
000000000447e610 000007fee7fed132 System.Web.HttpApplication+PipelineStepManager.ResumeSteps(System.Exception)
000000000447e7a0 000007fee7fcf599 System.Web.HttpApplication.BeginProcessRequestNotification(System.Web.HttpContext, System.AsyncCallback)
000000000447e7f0 000007fee80f5344 System.Web.HttpRuntime.ProcessRequestNotificationPrivate(System.Web.Hosting.IIS7WorkerRequest, System.Web.HttpContext)
000000000447e910 000007fee80f65bb System.Web.Hosting.PipelineRuntime.ProcessRequestNotificationHelper(IntPtr, IntPtr, IntPtr, Int32)
000000000447ea80 000007fee80f4994 System.Web.Hosting.PipelineRuntime.ProcessRequestNotification(IntPtr, IntPtr, IntPtr, Int32)
000000000447eae0 000007fef72701ea DomainNeutralILStubClass.IL_STUB(Int64, Int64, Int64, Int32)
000000000447f310 000007fee80f5424 DomainNeutralILStubClass.IL_STUB(IntPtr, System.Web.RequestNotificationStatus ByRef)
000000000447f3f0 000007fee80f65bb System.Web.Hosting.PipelineRuntime.ProcessRequestNotificationHelper(IntPtr, IntPtr, IntPtr, Int32)
000000000447f560 000007fee80f4994 System.Web.Hosting.PipelineRuntime.ProcessRequestNotification(IntPtr, IntPtr, IntPtr, Int32)
000000000447f5c0 000007fef727043b DomainNeutralILStubClass.IL_STUB(Int64, Int64, Int64, Int32)
OS Thread Id: 0x15ec (25)
Unable to walk the managed stack. The current thread is likely not a 
managed thread. You can run !threads to get a list of managed threads in
the process
OS Thread Id: 0x1958 (26)
Child-SP         RetAddr          Call Site
0000000004c1dd10 000007ff001e13d2 FileIO.performLockOperation()
0000000004c1dd90 000007feee323ec9 _Default.Page_Load(System.Object, System.EventArgs)
0000000004c1ddd0 000007fee7956aea System.Web.Util.CalliHelper.EventArgFunctionCaller(IntPtr, System.Object, System.Object, System.EventArgs)
0000000004c1de00 000007fee794d2c4 System.Web.Util.CalliEventHandlerDelegateProxy.Callback(System.Object, System.EventArgs)
0000000004c1de30 000007fee794d322 System.Web.UI.Control.OnLoad(System.EventArgs)
0000000004c1de70 000007fee79498ac System.Web.UI.Control.LoadRecursive()
0000000004c1dec0 000007fee7948db0 System.Web.UI.Page.ProcessRequestMain(Boolean, Boolean)
0000000004c1df90 000007fee7948cdb System.Web.UI.Page.ProcessRequest(Boolean, Boolean)
0000000004c1dff0 000007fee7948c70 System.Web.UI.Page.ProcessRequest()
0000000004c1e050 000007ff001e0c09 System.Web.UI.Page.ProcessRequest(System.Web.HttpContext)
0000000004c1e0b0 000007fee7950117 ASP.default_aspx.ProcessRequest(System.Web.HttpContext)
0000000004c1e0e0 000007fee791449b System.Web.HttpApplication+CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute()
0000000004c1e190 000007fee7ffbd41 System.Web.HttpApplication.ExecuteStep(IExecutionStep, Boolean ByRef)
0000000004c1e230 000007fee7fed132 System.Web.HttpApplication+PipelineStepManager.ResumeSteps(System.Exception)
0000000004c1e3c0 000007fee7fcf599 System.Web.HttpApplication.BeginProcessRequestNotification(System.Web.HttpContext, System.AsyncCallback)
0000000004c1e410 000007fee80f5344 System.Web.HttpRuntime.ProcessRequestNotificationPrivate(System.Web.Hosting.IIS7WorkerRequest, System.Web.HttpContext)
0000000004c1e530 000007fee80f65bb System.Web.Hosting.PipelineRuntime.ProcessRequestNotificationHelper(IntPtr, IntPtr, IntPtr, Int32)
0000000004c1e6a0 000007fee80f4994 System.Web.Hosting.PipelineRuntime.ProcessRequestNotification(IntPtr, IntPtr, IntPtr, Int32)
0000000004c1e700 000007fef72701ea DomainNeutralILStubClass.IL_STUB(Int64, Int64, Int64, Int32)
0000000004c1ef30 000007fee80f5424 DomainNeutralILStubClass.IL_STUB(IntPtr, System.Web.RequestNotificationStatus ByRef)
0000000004c1f010 000007fee80f65bb System.Web.Hosting.PipelineRuntime.ProcessRequestNotificationHelper(IntPtr, IntPtr, IntPtr, Int32)
0000000004c1f180 000007fee80f4994 System.Web.Hosting.PipelineRuntime.ProcessRequestNotification(IntPtr, IntPtr, IntPtr, Int32)
0000000004c1f1e0 000007fef727043b DomainNeutralILStubClass.IL_STUB(Int64, Int64, Int64, Int32)
OS Thread Id: 0x1e28 (27)
Child-SP         RetAddr          Call Site
000000000492dcf0 000007ff001e13d2 FileIO.performLockOperation()
000000000492dd70 000007feee323ec9 _Default.Page_Load(System.Object, System.EventArgs)
000000000492ddb0 000007fee7956aea System.Web.Util.CalliHelper.EventArgFunctionCaller(IntPtr, System.Object, System.Object, System.EventArgs)
000000000492dde0 000007fee794d2c4 System.Web.Util.CalliEventHandlerDelegateProxy.Callback(System.Object, System.EventArgs)
000000000492de10 000007fee794d322 System.Web.UI.Control.OnLoad(System.EventArgs)
000000000492de50 000007fee79498ac System.Web.UI.Control.LoadRecursive()
000000000492dea0 000007fee7948db0 System.Web.UI.Page.ProcessRequestMain(Boolean, Boolean)
000000000492df70 000007fee7948cdb System.Web.UI.Page.ProcessRequest(Boolean, Boolean)
000000000492dfd0 000007fee7948c70 System.Web.UI.Page.ProcessRequest()
000000000492e030 000007ff001e0c09 System.Web.UI.Page.ProcessRequest(System.Web.HttpContext)
000000000492e090 000007fee7950117 ASP.default_aspx.ProcessRequest(System.Web.HttpContext)
000000000492e0c0 000007fee791449b System.Web.HttpApplication+CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute()
000000000492e170 000007fee7ffbd41 System.Web.HttpApplication.ExecuteStep(IExecutionStep, Boolean ByRef)
000000000492e210 000007fee7fed132 System.Web.HttpApplication+PipelineStepManager.ResumeSteps(System.Exception)
000000000492e3a0 000007fee7fcf599 System.Web.HttpApplication.BeginProcessRequestNotification(System.Web.HttpContext, System.AsyncCallback)
000000000492e3f0 000007fee80f5344 System.Web.HttpRuntime.ProcessRequestNotificationPrivate(System.Web.Hosting.IIS7WorkerRequest, System.Web.HttpContext)
000000000492e510 000007fee80f65bb System.Web.Hosting.PipelineRuntime.ProcessRequestNotificationHelper(IntPtr, IntPtr, IntPtr, Int32)
000000000492e680 000007fee80f4994 System.Web.Hosting.PipelineRuntime.ProcessRequestNotification(IntPtr, IntPtr, IntPtr, Int32)
000000000492e6e0 000007fef72701ea DomainNeutralILStubClass.IL_STUB(Int64, Int64, Int64, Int32)
000000000492ef10 000007fee80f5424 DomainNeutralILStubClass.IL_STUB(IntPtr, System.Web.RequestNotificationStatus ByRef)
000000000492eff0 000007fee80f65bb System.Web.Hosting.PipelineRuntime.ProcessRequestNotificationHelper(IntPtr, IntPtr, IntPtr, Int32)
000000000492f160 000007fee80f4994 System.Web.Hosting.PipelineRuntime.ProcessRequestNotification(IntPtr, IntPtr, IntPtr, Int32)
000000000492f1c0 000007fef727043b DomainNeutralILStubClass.IL_STUB(Int64, Int64, Int64, Int32)
OS Thread Id: 0x1c38 (28)
Child-SP         RetAddr          Call Site
0000000004d0e0b0 000007ff001e13d2 FileIO.performLockOperation()
0000000004d0e130 000007feee323ec9 _Default.Page_Load(System.Object, System.EventArgs)
0000000004d0e170 000007fee7956aea System.Web.Util.CalliHelper.EventArgFunctionCaller(IntPtr, System.Object, System.Object, System.EventArgs)
0000000004d0e1a0 000007fee794d2c4 System.Web.Util.CalliEventHandlerDelegateProxy.Callback(System.Object, System.EventArgs)
0000000004d0e1d0 000007fee794d322 System.Web.UI.Control.OnLoad(System.EventArgs)
0000000004d0e210 000007fee79498ac System.Web.UI.Control.LoadRecursive()
0000000004d0e260 000007fee7948db0 System.Web.UI.Page.ProcessRequestMain(Boolean, Boolean)
0000000004d0e330 000007fee7948cdb System.Web.UI.Page.ProcessRequest(Boolean, Boolean)
0000000004d0e390 000007fee7948c70 System.Web.UI.Page.ProcessRequest()
0000000004d0e3f0 000007ff001e0c09 System.Web.UI.Page.ProcessRequest(System.Web.HttpContext)
0000000004d0e450 000007fee7950117 ASP.default_aspx.ProcessRequest(System.Web.HttpContext)
0000000004d0e480 000007fee791449b System.Web.HttpApplication+CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute()
0000000004d0e530 000007fee7ffbd41 System.Web.HttpApplication.ExecuteStep(IExecutionStep, Boolean ByRef)
0000000004d0e5d0 000007fee7fed132 System.Web.HttpApplication+PipelineStepManager.ResumeSteps(System.Exception)
0000000004d0e760 000007fee7fcf599 System.Web.HttpApplication.BeginProcessRequestNotification(System.Web.HttpContext, System.AsyncCallback)
0000000004d0e7b0 000007fee80f5344 System.Web.HttpRuntime.ProcessRequestNotificationPrivate(System.Web.Hosting.IIS7WorkerRequest, System.Web.HttpContext)
0000000004d0e8d0 000007fee80f65bb System.Web.Hosting.PipelineRuntime.ProcessRequestNotificationHelper(IntPtr, IntPtr, IntPtr, Int32)
0000000004d0ea40 000007fee80f4994 System.Web.Hosting.PipelineRuntime.ProcessRequestNotification(IntPtr, IntPtr, IntPtr, Int32)
0000000004d0eaa0 000007fef72701ea DomainNeutralILStubClass.IL_STUB(Int64, Int64, Int64, Int32)
0000000004d0f2d0 000007fee80f5424 DomainNeutralILStubClass.IL_STUB(IntPtr, System.Web.RequestNotificationStatus ByRef)
0000000004d0f3b0 000007fee80f65bb System.Web.Hosting.PipelineRuntime.ProcessRequestNotificationHelper(IntPtr, IntPtr, IntPtr, Int32)
0000000004d0f520 000007fee80f4994 System.Web.Hosting.PipelineRuntime.ProcessRequestNotification(IntPtr, IntPtr, IntPtr, Int32)
0000000004d0f580 000007fef727043b DomainNeutralILStubClass.IL_STUB(Int64, Int64, Int64, Int32</pre>
</div>

<p>So, what does this tell us?</p>

<p>Well, obviously we have four threads that call my function FileIO.performLockOperation() from Page_Load.</p>

<p>Please note that we don't have any additional callstack, and since the performLockOperation-function was named by me it could just as well have been named &quot;foo&quot;. In order to find out that these threads are actually waiting for a lock we need to look at the native callstack using the kb-command. Let's take a look at thread 24: </p>

<div class="DebugSample">
  <pre>0:029&gt; ~24kb
ntdll!NtDelayExecution+0xa
kernel32!SleepEx+0x84
mscorwks!EESleepEx+0x2d
mscorwks!Thread::UserSleep+0x71
mscorwks!<font color="#ff0000">ThreadNative::Sleep</font>+0xf9
App_Code_tvh3usvo!<font color="#ff0000">FileIO.performLockOperation</font>()+0x8a
App_Web_uywrbugj!_Default.Page_Load(System.Object, System.EventArgs)+0x32
System_Web_RegularExpressions_ni!System.Web.Util.CalliHelper.EventArgFunctionCaller(IntPtr, System.Object, System.Object, System.EventArgs)+0x19
System_Web_ni!System.Web.Util.CalliEventHandlerDelegateProxy.Callback(System.Object, System.EventArgs)+0x2a
System_Web_ni!System.Web.UI.Control.OnLoad(System.EventArgs)+0x84
System_Web_ni!System.Web.UI.Control.LoadRecursive()+0x42
System_Web_ni!System.Web.UI.Page.ProcessRequestMain(Boolean, Boolean)+0x97c
System_Web_ni!System.Web.UI.Page.ProcessRequest(Boolean, Boolean)+0xa0
System_Web_ni!System.Web.UI.Page.ProcessRequest()+0x5b
System_Web_ni!System.Web.UI.Page.ProcessRequest(System.Web.HttpContext)+0xf0
App_Web_uywrbugj!ASP.default_aspx.ProcessRequest(System.Web.HttpContext)+0x9
System_Web_ni!System.Web.HttpApplication+CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute()+0x257
System_Web_ni!System.Web.HttpApplication.ExecuteStep(IExecutionStep, Boolean ByRef)+0xab
System_Web_ni!System.Web.HttpApplication+PipelineStepManager.ResumeSteps(System.Exception)+0x501
System_Web_ni!System.Web.HttpApplication.BeginProcessRequestNotification(System.Web.HttpContext, System.AsyncCallback)+0x72</pre>
</div>

<p>Apparently we entered FileIO.performLockOperation, and then called sleep, (which is what we're doing in this repro in order to simulate a slow IO operation.) So, what do the other threads look like? Here's thread 26:</p>

<div class="DebugSample">
  <pre>0:029&gt; ~26kb
ntdll!ZwWaitForMultipleObjects+0xa
kernel32!WaitForMultipleObjectsEx+0x10b
mscorwks!WaitForMultipleObjectsEx_SO_TOLERANT+0xc1
mscorwks!Thread::DoAppropriateAptStateWait+0x41
mscorwks!Thread::DoAppropriateWaitWorker+0x191
mscorwks!Thread::DoAppropriateWait+0x5c
mscorwks!<font color="#ff0000">CLREvent::WaitEx</font>+0xbe
mscorwks!AwareLock::EnterEpilog+0xc9
mscorwks!AwareLock::Enter+0x72
mscorwks!AwareLock::Contention+0x1fb
mscorwks!JITutil_MonContention+0xdf
App_Code_tvh3usvo!<font color="#ff0000">FileIO.performLockOperation</font>()+0x7f
App_Web_uywrbugj!_Default.Page_Load(System.Object, System.EventArgs)+0x32
System_Web_RegularExpressions_ni!System.Web.Util.CalliHelper.EventArgFunctionCaller(IntPtr, System.Object, System.Object, System.EventArgs)+0x19
System_Web_ni!System.Web.Util.CalliEventHandlerDelegateProxy.Callback(System.Object, System.EventArgs)+0x2a
System_Web_ni!System.Web.UI.Control.OnLoad(System.EventArgs)+0x84
System_Web_ni!System.Web.UI.Control.LoadRecursive()+0x42
System_Web_ni!System.Web.UI.Page.ProcessRequestMain(Boolean, Boolean)+0x97c
System_Web_ni!System.Web.UI.Page.ProcessRequest(Boolean, Boolean)+0xa0
System_Web_ni!System.Web.UI.Page.ProcessRequest()+0x5b</pre>
</div>

<p>This is one of the threads waiting for the critical section. It then found that it was unable to get a lock and so began waiting for the critical section on thread 24 to end.</p>

<h1>Resolving the problem</h1>

<p>This is the tricky part. There is no quick-fix for this. We can use the debugger to identify the bottleneck, but after that we'll need to review our design in order to get this working smoothly. A couple of generic things to try would be the following:</p>

<ul>
  <li>Review what you're doing inside the critical section. Is it really necessary to perform all of the operations you're doing, or would it be possible to do some/all of them outside the scope of the critical section?</li>

  <li>Identify the reason for the lock taking so much time. Can it be resolved by load-balancing or clustering the resource we're waiting for?</li>

  <li>If we're waiting for another server, make sure the physical infrastructure is okay. Are network response times within the expected parameters or do you need to fix your wiring, router, etc?</li>

  <li>Are <em>all </em>calls to the critical section taking the same amount of time, or are there certain calls that take an <em>exceptional</em> amount of time? Perhaps most calls to the function are just fine, but intermittently a call comes along that tries to get <em>everything </em>from the AD, database, etc. In order to investigate this I'd use the commands outlined in <a href="http://blogs.msdn.com/johan/archive/2007/11/26/getting-started-with-windbg-part-ii.aspx">Getting started with windbg -part II</a>. Identify the thread owning the lock and investigate the callstack and stack objects using !clrstack and !dso. Use !dso and !do to query the stack objects and try to find the SQL query or AD query that is causing the thread to take such a long time to finish. Is the query significantly different from the ones waiting to execute, then this is most likely our culprit.</li>
</ul>

<h1>Post Script</h1>

<p>A quick thought on locks and their limits:</p>

<p>Locks do not scale well. A lock can only be made within a specific process, so if you're using a web farm, or in any other way more than one w3wp.exe, then you will not be able to lock <em>all </em>processes. In other words. Server 1 can get a lock, and so can Server 2. Both will happily execute their code independent of each other. For products such as SQL server you'd deal with this in your SQL query, but if you're performing other operations, such as File IO you might have to work around this by using the same approach as Ms Word. Create a lock file in a shared space, and before you enter your critical section you simply check if the file exists:</p>

<ol>
  <li>You are entering your critical section. Look for lock file in shared location</li>

  <li>If file exists, then wait</li>

  <li>If/when file doesn't/no longer exist, create file and enter critical section</li>

  <li>Make sure you have <em>solid</em> exception handling within the critical section so that you under no circumstances leave the critical section without removing the lock file.</li>

  <li>When done, remove lock file</li>
</ol>

<p>/ Johan</p>]]></content:encoded>
    </item>
    <item>
      <title>Problems with Flash-content in the WebBrowser control</title>
      <link>https://docs.microsoft.com/archive/blogs/johan/problems-with-flash-content-in-the-webbrowser-control</link>
      <pubDate>Thu, 06 Aug 2009 10:59:34 GMT</pubDate>
      <dc:creator><![CDATA[JohanSt]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/johan/2009/08/06/problems-with-flash-content-in-the-webbrowser-control/</guid>
      <description><![CDATA[A recent case I worked on involved the following scenario.  Problem description  The client was...]]></description>
      <content:encoded><![CDATA[<p>A recent case I worked on involved the following scenario.</p>  <h1>Problem description</h1>  <p>The client was building a kiosk-like application. I.e. a WinForms application with the WebBrowser control slapped onto it. The application worked fine for the most part, but they'd found that when viewing video via <a href="http://www.facebook.com/" target="_blank">facebook</a> they were only able to view the video the first time. Any additional attempt to view the video would fail with a custom error from the facebook application stating that the video was either restricted or no longer available.</p>  <p>This only happened when viewing the page via the WinForms application. Using IE directly worked just fine. We also found that this problem occurred with both IE7 and IE8 installed, so it seemed not to be related to the browser version.</p>  <p>Other sites using the Adobe Flash player to display video, such as <a href="http://video.msn.com" target="_blank">MSN</a> or <a href="https://www.youtube.com/" target="_blank">Youtube</a> worked just fine.</p>  <h1>Troubleshooting</h1>  <p>Using the Developer tools included in IE8 I found that the facebook application displays a placeholder image with a play-button. Once that button is clicked the .swf player is loaded via client-side script. The .swf player then downloads the .mp4 that is to be displayed and divides it into suitable chunks.</p>  <p>Fiddler traces revealed that the mp4 was downloaded when using IE but not when using the WinForms application. No errors were reported, instead the request was simply never made.</p>  <p>We removed all code behind. All that remained was the On_Load event that set a starting page for the WebBrowser control, still we were unable to successfully load the movie.</p>  <p>Adding facebook to the trusted zone changed nothing.</p>  <p>Using the COM-version of the WebBrowser control still reproduced the problem.</p>  <p>I then suspected restrictions in cross-domain access or similar, (facebook uses a lot of different domains,) but couldn't find anything conclusive.</p>  <p>Finally I stumbled upon the root cause.</p>  <h1>Cause</h1>  <p>The problem is due to a bug within the Adobe Flash-player: <a href="http://bugs.adobe.com/jira/browse/FP-256">http://bugs.adobe.com/jira/browse/FP-256</a></p>  <p>The problem occurs when dynamically trying to display a cached .swf application with an external interface through script. So, another quick repro would be the following (Copied from the Adobe bug report):</p>  <ol>   <li>Create a C# application with an embedded WebBrowser control.</li>    <li>Load a HTML page with no content.</li>    <li>Via JavaScript, add a SWF with external interface to the page via an object tag. (At this point I see server traffic, requesting the SWF.)</li>    <li>From JavaScript, access the external interface of the SWF. Works OK.</li>    <li>Browse to a second web page.</li>    <li>Browse back to the empty one.</li>    <li>Via JavaScript, add the SWF again. Cannot contact the external interface. (There is no server traffic, indicating that the SWF is already being cached.)</li> </ol>  <h1>Solution</h1>  <p>While waiting for a fix from Adobe the only way to circumvent this is to manually remove the cached .swf. Article <a href="http://support.microsoft.com/kb/262110" target="_blank">262110</a> describes in detail how you can do this. Unfortunately this can be a bit tricky some times. In the sample repro above you'd resolve it by simply removing all .swf items from the cache upon page-load, but this wouldn't work in the facebook situation, since it might use the same control repeatedly without refreshing the page in between. Depending on your level of control over the target platform it might be easier to simply turn of caching.</p>  <p>/ Johan</p>]]></content:encoded>
    </item>
    <item>
      <title>Adding Server ROles to an IIS installation on an RODC</title>
      <link>https://docs.microsoft.com/archive/blogs/johan/adding-server-roles-to-an-iis-installation-on-an-rodc</link>
      <pubDate>Tue, 05 May 2009 10:10:15 GMT</pubDate>
      <dc:creator><![CDATA[JohanSt]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/johan/2009/05/05/adding-server-roles-to-an-iis-installation-on-an-rodc/</guid>
      <description><![CDATA[In a recent case I was involved with I stumbled upon something quite interesting. The customer had...]]></description>
      <content:encoded><![CDATA[<p>In a recent case I was involved with I stumbled upon something quite interesting. The customer had set up a brand new Windows 2008 Server running IIS, and made it into a <em>Read Only Domain Controller</em> (RODC). Having done this they now wanted to add the FTP-server Role to the existing IIS installation and found that they couldn't.</p>  <p>The reason for this is that the RODC is quite picky about what server roles and features it will allow you to install. I recommend looking at the following articles, but they still don't cover everything.</p>  <p>Applications That Are Known to Work with RODCs   <br /><a title="http://technet.microsoft.com/en-us/library/cc732790.aspx" href="http://technet.microsoft.com/en-us/library/cc732790.aspx">http://technet.microsoft.com/en-us/library/cc732790.aspx</a></p>  <p>Planning for Application Compatibility with RODCs   <br /><a title="http://technet.microsoft.com/en-us/library/cc731746.aspx" href="http://technet.microsoft.com/en-us/library/cc731746.aspx">http://technet.microsoft.com/en-us/library/cc731746.aspx</a></p>  <p>The main lesson to be learned is that although the application is listed as known to work with RODCs that doesn't necessarily mean it installs well once the server has been promoted to RODC. When it comes to FTP you have two valid options to get this working:</p>  <ol>   <li>Install the FTP server <em>before</em> promoting the server to RODC</li>    <li>Install the <a href="http://www.microsoft.com/downloads/details.aspx?displaylang=en&amp;FamilyID=b7f5b652-8c5c-447a-88b8-8cfc5c13f571" target="_blank">FTP Service 7.5 for IIS7</a>. This is a stand-alone installer and works just fine.</li> </ol>  <p>/ Johan</p>]]></content:encoded>
    </item>
  </channel>
</rss>