<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://blogs.msdn.com/utility/FeedStylesheets/atom.xsl" media="screen"?><feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en-US"><title type="html">Kristoffer's tidbits</title><subtitle type="html">Bits and pieces of useful information by Kristoffer Henriksson</subtitle><id>http://blogs.msdn.com/kristoffer/atom.xml</id><link rel="alternate" type="text/html" href="http://blogs.msdn.com/kristoffer/default.aspx" /><link rel="self" type="application/atom+xml" href="http://blogs.msdn.com/kristoffer/atom.xml" /><generator uri="http://communityserver.org" version="2.1.61025.2">Community Server</generator><updated>2006-12-29T13:51:10Z</updated><entry><title>OutOfMemoryException is special</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/kristoffer/archive/2009/02/25/outofmemoryexception-is-special.aspx" /><id>http://blogs.msdn.com/kristoffer/archive/2009/02/25/outofmemoryexception-is-special.aspx</id><published>2009-02-25T17:25:00Z</published><updated>2009-02-25T17:25:00Z</updated><content type="html">&lt;p&gt;Consider the humble OutOfMemoryException and its most common usage. If it is thrown when the system is well and truly out of memory then how would the system allocate enough memory to create a new instance of OutOfMemoryException? Luckily this problem has a simple solution: OutOfMemoryException is allocated up front so it's available when it needs to be thrown.&lt;/p&gt;&lt;p&gt;The .NET runtime does first try to create a new OutOfMemoryException instance but if it fails it will fall back to the preallocated instance so there is always an exception available to be thrown. &lt;/p&gt;&lt;p&gt;Some other exceptions are preallocated: StackOverflowException, ExecutionEngineException, and ThreadAbortException.&lt;br&gt;&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9444365" width="1" height="1"&gt;</content><author><name>Kristoffer</name><uri>http://blogs.msdn.com/members/Kristoffer.aspx</uri></author><category term="Interesting" scheme="http://blogs.msdn.com/kristoffer/archive/tags/Interesting/default.aspx" /><category term=".NET" scheme="http://blogs.msdn.com/kristoffer/archive/tags/.NET/default.aspx" /></entry><entry><title>Troubleshooting a failed Virtual Earth 3D installation</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/kristoffer/archive/2008/05/16/troubleshooting-a-failed-virtual-earth-3d-installation.aspx" /><id>http://blogs.msdn.com/kristoffer/archive/2008/05/16/troubleshooting-a-failed-virtual-earth-3d-installation.aspx</id><published>2008-05-16T19:54:00Z</published><updated>2008-05-16T19:54:00Z</updated><content type="html">&lt;p&gt;The Virtual Earth 3D setup program is a small executable that downloads and installs pre-requisites if they're not already installed and then the correct MSI for your OS flavor (32 or 64 bit). The pre-requisites are Windows Imaging Components and .NET Framework 2.0. WIC comes with Vista and XP sp3 and doesn't need to be downloaded on those platforms. The setup program logs its status to a file named VirtualEarth3DInstallLog.txt in the Temp folder. On a default Windows XP installation the Temp folder is located at C:\Documents and Settings\[username]\Local Settings\Temp.&lt;br&gt;&lt;/p&gt;&lt;p&gt;After the pre-requisites have been validated VirtualEarth3D.msi or VirtualEarth3D64.msi are downloaded and installed.&amp;nbsp; The 64 bit MSI contains both 32 and 64 bit modules so you can run internet explorer in 32 or 64 bit mode. The MSI log is stored in MsiInstall.log, also in the Temp folder.&lt;/p&gt;&lt;p&gt;So what errors go to what log?&lt;/p&gt;&lt;ul&gt;&lt;li&gt;If the error happens in the Setup program, for example a failure to download a prerequisite or the MSI, VirtualEarth3DInstallLog.txt will have an error message with the details.&lt;/li&gt;&lt;li&gt;If the error happens once Setup starts running the Virtual Earth 3D MSI MsiInstall.log will contain the details.&lt;/li&gt;&lt;/ul&gt;&lt;br&gt;If you still have problems installing Virtual Earth 3D, &lt;a href="https://support.live.com/eform.aspx?productKey=wllocal&amp;amp;ct=eformts" mce_href="https://support.live.com/eform.aspx?productKey=wllocal&amp;amp;ct=eformts"&gt;Live Maps support&lt;/a&gt; is only a click away.&lt;br&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=8514828" width="1" height="1"&gt;</content><author><name>Kristoffer</name><uri>http://blogs.msdn.com/members/Kristoffer.aspx</uri></author><category term="Virtual Earth 3D" scheme="http://blogs.msdn.com/kristoffer/archive/tags/Virtual+Earth+3D/default.aspx" /></entry><entry><title>How does Virtual Earth 3D find and load plugins?</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/kristoffer/archive/2007/12/07/how-does-virtual-earth-3d-find-and-load-plugins.aspx" /><id>http://blogs.msdn.com/kristoffer/archive/2007/12/07/how-does-virtual-earth-3d-find-and-load-plugins.aspx</id><published>2007-12-07T18:45:00Z</published><updated>2007-12-07T18:45:00Z</updated><content type="html">&lt;p&gt;On startup VE3D looks in the Plugins folder of the install directory (ProgramFiles\Virtual Earth 3D) and iterates through the assemblies in each subfolder of Plugins. A plugin named Sample would install itself as C:\Program Files\Virtual Earth 3D\Plugins\Sample\Sample.dll. Note that this folder doesn't exist by default so your plugin installer will need to create it.&lt;br&gt; &lt;/p&gt;
&lt;p&gt;Next each assembly is probed for classes that descend from &lt;span style="font-size: 10pt; font-family: Courier New;"&gt;&lt;span style="color: black;"&gt;Microsoft.MapPoint.PlugIns.&lt;/span&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;PlugIn&lt;/span&gt;&lt;/span&gt;. For security reasons only assemblies that are in the GAC are allowed to run. The good news is that we are investigating allowing partially trusted plugins for our next release. This means you will be able to visit a website and have it load its own plugins to add new functionality to VE3D without forcing you to go through an install process. Since we're still in the early parts of our next release I don't know for sure if this will make the cut but it is something we would like to add.&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=6696138" width="1" height="1"&gt;</content><author><name>Kristoffer</name><uri>http://blogs.msdn.com/members/Kristoffer.aspx</uri></author><category term="Virtual Earth 3D" scheme="http://blogs.msdn.com/kristoffer/archive/tags/Virtual+Earth+3D/default.aspx" /><category term="Virtual Earth 3D Plugins" scheme="http://blogs.msdn.com/kristoffer/archive/tags/Virtual+Earth+3D+Plugins/default.aspx" /></entry><entry><title>Using a plugin to add a billboard to Virtual Earth 3D</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/kristoffer/archive/2007/11/14/using-a-plugin-to-add-a-billboard-to-virtual-earth-3d.aspx" /><id>http://blogs.msdn.com/kristoffer/archive/2007/11/14/using-a-plugin-to-add-a-billboard-to-virtual-earth-3d.aspx</id><published>2007-11-14T20:10:00Z</published><updated>2007-11-14T20:10:00Z</updated><content type="html">&lt;P&gt;To add objects to the VE3D world we need to create our own actor that knows how to render itself.&lt;/P&gt;
&lt;P&gt;Actors descend from &lt;SPAN style="FONT-FAMILY: Courier New"&gt;Microsoft.MapPoint.Rendering3D.Steps.Actors.&lt;SPAN style="COLOR: #2b91af"&gt;Actor&lt;/SPAN&gt;&lt;/SPAN&gt; and must override the &lt;SPAN style="FONT-FAMILY: Courier New"&gt;Render&lt;/SPAN&gt; method. When it comes time to render a frame, all actors have their Render method called to queue up renderable objects. To show a billboard we'll create a BillboardActor and use a SpriteGraphicsObject to render our image.&lt;/P&gt;
&lt;DIV style="FONT-SIZE: 10pt; BACKGROUND: white; COLOR: black; FONT-FAMILY: Courier New"&gt;
&lt;P style="MARGIN: 0px"&gt;&lt;SPAN style="COLOR: blue"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; public&lt;/SPAN&gt; BillboardActor(&lt;SPAN style="COLOR: #2b91af"&gt;LatLonAlt&lt;/SPAN&gt; position)&lt;/P&gt;
&lt;P style="MARGIN: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/P&gt;
&lt;P style="MARGIN: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN style="COLOR: blue"&gt;this&lt;/SPAN&gt;.texture = &lt;SPAN style="COLOR: #2b91af"&gt;Texture&lt;/SPAN&gt;.FromResource(&lt;SPAN style="COLOR: blue"&gt;this&lt;/SPAN&gt;.GetType().Assembly, &lt;SPAN style="COLOR: #a31515"&gt;"VirtualEarth3DSamplePlugins.Billboard.Flower.png"&lt;/SPAN&gt;);&lt;/P&gt;
&lt;P style="MARGIN: 0px" mce_keep="true"&gt;&amp;nbsp;&lt;/P&gt;
&lt;P style="MARGIN: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN style="COLOR: blue"&gt;this&lt;/SPAN&gt;.billboard = &lt;SPAN style="COLOR: blue"&gt;new&lt;/SPAN&gt; &lt;SPAN style="COLOR: #2b91af"&gt;SpriteGraphicsObject&lt;/SPAN&gt;();&lt;/P&gt;
&lt;P style="MARGIN: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN style="COLOR: blue"&gt;this&lt;/SPAN&gt;.billboard.Texture = &lt;SPAN style="COLOR: blue"&gt;this&lt;/SPAN&gt;.texture;&lt;/P&gt;
&lt;P style="MARGIN: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN style="COLOR: blue"&gt;this&lt;/SPAN&gt;.billboard.Mode = &lt;SPAN style="COLOR: #2b91af"&gt;SpriteMode&lt;/SPAN&gt;.Billboard;&lt;/P&gt;
&lt;P style="MARGIN: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN style="COLOR: blue"&gt;this&lt;/SPAN&gt;.billboard.Scale = &lt;SPAN style="COLOR: blue"&gt;new&lt;/SPAN&gt; &lt;SPAN style="COLOR: #2b91af"&gt;Vector2D&lt;/SPAN&gt;(1000, 1000);&lt;/P&gt;
&lt;P style="MARGIN: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN style="COLOR: blue"&gt;this&lt;/SPAN&gt;.billboard.Color = &lt;SPAN style="COLOR: #2b91af"&gt;Color&lt;/SPAN&gt;.White;&lt;/P&gt;
&lt;P style="MARGIN: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN style="COLOR: blue"&gt;this&lt;/SPAN&gt;.billboard.AlphaEnable = &lt;SPAN style="COLOR: blue"&gt;true&lt;/SPAN&gt;;&lt;/P&gt;
&lt;P style="MARGIN: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN style="COLOR: blue"&gt;this&lt;/SPAN&gt;.billboard.Position = position.GetVector();&lt;/P&gt;
&lt;P style="MARGIN: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/P&gt;&lt;/DIV&gt;
&lt;DIV style="FONT-SIZE: 10pt; BACKGROUND: white; COLOR: black; FONT-FAMILY: Courier New"&gt;
&lt;P style="MARGIN: 0px"&gt;&lt;SPAN style="COLOR: blue"&gt;&lt;/SPAN&gt;&amp;nbsp;&lt;/P&gt;
&lt;P style="MARGIN: 0px"&gt;&lt;SPAN style="COLOR: blue"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;public&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;override&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;void&lt;/SPAN&gt; Render(Microsoft.MapPoint.Rendering3D.Scene.&lt;SPAN style="COLOR: #2b91af"&gt;SceneState&lt;/SPAN&gt; sceneState)&lt;/P&gt;
&lt;P style="MARGIN: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/P&gt;
&lt;P style="MARGIN: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN style="COLOR: #2b91af"&gt;RenderQueues&lt;/SPAN&gt; renderQueues = sceneState.GetData&amp;lt;&lt;SPAN style="COLOR: #2b91af"&gt;RenderQueues&lt;/SPAN&gt;&amp;gt;();&lt;/P&gt;
&lt;P style="MARGIN: 0px" mce_keep="true"&gt;&amp;nbsp;&lt;/P&gt;
&lt;P style="MARGIN: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; renderQueues.AddAlphaRenderable(0, &lt;SPAN style="COLOR: blue"&gt;this&lt;/SPAN&gt;.billboard);&lt;/P&gt;
&lt;P style="MARGIN: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/P&gt;&lt;/DIV&gt;
&lt;P&gt;Once we have our actor we just need to add it to the ActorManager so it knows to start rendering it. We can do this in our Activate method on the plugin.&lt;/P&gt;
&lt;DIV style="FONT-SIZE: 10pt; BACKGROUND: white; COLOR: black; FONT-FAMILY: Courier New"&gt;
&lt;P style="MARGIN: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN style="COLOR: #2b91af"&gt;LatLonAlt&lt;/SPAN&gt; position = &lt;SPAN style="COLOR: #2b91af"&gt;LatLonAlt&lt;/SPAN&gt;.CreateUsingDegrees(46.849743288383046, -121.7498016357422, 5000);&lt;/P&gt;
&lt;P style="MARGIN: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN style="COLOR: green"&gt;// Add the actor at the specified position&lt;/SPAN&gt;&lt;/P&gt;
&lt;P style="MARGIN: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN style="COLOR: blue"&gt;this&lt;/SPAN&gt;.Host.Actors.Add(&lt;SPAN style="COLOR: blue"&gt;new&lt;/SPAN&gt; &lt;SPAN style="COLOR: #2b91af"&gt;BillboardActor&lt;/SPAN&gt;(position));&lt;/P&gt;&lt;/DIV&gt;
&lt;P&gt;&lt;IMG title="Billboard in action" style="WIDTH: 886px; HEIGHT: 714px" height=714 alt="Billboard in action" src="http://kristoffer.members.winisp.net/Images/VirtualEarth3DPlugins/VirtualEarth3DBillboardPlugin.png" width=886 border=0 mce_src="http://kristoffer.members.winisp.net/Images/VirtualEarth3DPlugins/VirtualEarth3DBillboardPlugin.png"&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;You can browse the source code for the actor and the plugin online or download the entire project.&lt;BR&gt;&lt;A title="BillboardActor.cs source code" href="http://blogs.msdn.com/Kristoffer/pages/billboardactor-cs.aspx" mce_href="http://blogs.msdn.com/Kristoffer/pages/billboardactor-cs.aspx"&gt;BillboardActor.cs&lt;/A&gt;&amp;nbsp;| &lt;A title="BillboardPlugin.cs source code" href="http://blogs.msdn.com/Kristoffer/pages/billboardplugin-cs.aspx" mce_href="http://blogs.msdn.com/Kristoffer/pages/billboardplugin-cs.aspx"&gt;BillboardPlugin.cs&lt;/A&gt;&lt;BR&gt;&lt;A href="http://kristoffer.members.winisp.net/VE3D/VirtualEarth3DPlugins.zip"&gt;Download project&lt;/P&gt;&lt;/A&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=6223935" width="1" height="1"&gt;</content><author><name>Kristoffer</name><uri>http://blogs.msdn.com/members/Kristoffer.aspx</uri></author><category term="Virtual Earth 3D" scheme="http://blogs.msdn.com/kristoffer/archive/tags/Virtual+Earth+3D/default.aspx" /><category term="Virtual Earth 3D Plugins" scheme="http://blogs.msdn.com/kristoffer/archive/tags/Virtual+Earth+3D+Plugins/default.aspx" /></entry><entry><title>Creating a Hello World plugin for Virtual Earth 3D</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/kristoffer/archive/2007/11/13/creating-a-hello-world-plugin-for-virtual-earth-3d.aspx" /><id>http://blogs.msdn.com/kristoffer/archive/2007/11/13/creating-a-hello-world-plugin-for-virtual-earth-3d.aspx</id><published>2007-11-13T17:33:00Z</published><updated>2007-11-13T17:33:00Z</updated><content type="html">&lt;p&gt;With latest&amp;nbsp;release of the Virtual Earth 3D release we now support loading plugins to perform additional functionality not implemented in the main product. Two new features of the release are even implemented as plugins (bird's eye photos and user created models).&lt;/p&gt;
&lt;p&gt;To get you started with creating your own plugin for VE3D here's a short starter guide using Visual Studio 2005.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Create a new C# Class Library project, call it HelloWorld.&lt;/li&gt;
&lt;li&gt;Add references to the following assemblies located in C:\Program Files\Virtual Earth 3D:&lt;br&gt;
&lt;ul&gt;
&lt;li&gt;Microsoft.MapPoint.Rendering3D.dll&lt;/li&gt;
&lt;li&gt;Microsoft.MapPoint.Rendering3D.Utility.dll&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;
&lt;li&gt;Rename Class1.cs to HelloWorldPlugin.cs and paste the following code over the file:&lt;br&gt;
&lt;div style="background: white none repeat scroll 0% 50%; font-size: 10pt; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial; color: black; font-family: Courier New;"&gt;
&lt;p style="margin: 0px;"&gt;&lt;span style="color: blue;"&gt;using&lt;/span&gt; System;&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;&lt;span style="color: blue;"&gt;using&lt;/span&gt; System.Collections.Generic;&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;&lt;span style="color: blue;"&gt;using&lt;/span&gt; System.Text;&lt;/p&gt;
&lt;p style="margin: 0px;" mce_keep="true"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;&lt;span style="color: blue;"&gt;using&lt;/span&gt; Microsoft.MapPoint.PlugIns;&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;&lt;span style="color: blue;"&gt;using&lt;/span&gt; Microsoft.MapPoint.Rendering3D;&lt;/p&gt;
&lt;p style="margin: 0px;" mce_keep="true"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;&lt;span style="color: blue;"&gt;namespace&lt;/span&gt; VirtualEarth3DSamplePlugins.HelloWorld&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;{&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;public&lt;/span&gt; &lt;span style="color: blue;"&gt;class&lt;/span&gt; &lt;span style="color: rgb(43, 145, 175);"&gt;HelloWorldPlugin&lt;/span&gt; : PlugIn&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;&lt;span style="color: blue;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; #region&lt;/span&gt; Constructor&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;public&lt;/span&gt; HelloWorldPlugin(Host host)&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; : &lt;span style="color: blue;"&gt;base&lt;/span&gt;(host)&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;&lt;span style="color: blue;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; #endregion&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;&lt;span style="color: blue;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; #region&lt;/span&gt; Overrides&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;public&lt;/span&gt; &lt;span style="color: blue;"&gt;override&lt;/span&gt; &lt;span style="color: blue;"&gt;void&lt;/span&gt; Activate(&lt;span style="color: blue;"&gt;object&lt;/span&gt; activationObject)&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;this&lt;/span&gt;.Host.Notifications.Display(&lt;span style="color: rgb(163, 21, 21);"&gt;"Hello world!"&lt;/span&gt;);&lt;/p&gt;
&lt;p style="margin: 0px;" mce_keep="true"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;base&lt;/span&gt;.Activate(activationObject);&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;public&lt;/span&gt; &lt;span style="color: blue;"&gt;override&lt;/span&gt; &lt;span style="color: blue;"&gt;string&lt;/span&gt; Name&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;get&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;return&lt;/span&gt; &lt;span style="color: rgb(163, 21, 21);"&gt;"HelloWorldPlugin"&lt;/span&gt;;&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;&lt;span style="color: blue;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; #endregion&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;}&lt;/p&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;Go to Project Properties, Signing, check &lt;b&gt;Sign the assembly&lt;/b&gt; and create a new key to sign your project with. Only plugins that are in the GAC will be granted permissions to run and only strongly named assemblies may be placed in the GAC. 
&lt;p&gt;Build your project and copy HelloWorld.dll to a new folder named &lt;b&gt;C:\Program Files\Virtual Earth 3D\Plugins\HelloWorld&lt;/b&gt;. From a &lt;b&gt;Visual Studio 2005 Command Prompt&lt;/b&gt; run &lt;br&gt;&lt;font style="font-family: Courier New;"&gt;gacutil -i "C:\Program Files\Virtual Earth 3D\Plugins\HelloWorld\HelloWorld.dll"&lt;/font&gt;&lt;/p&gt;&lt;/li&gt;&lt;/ol&gt;
&lt;p&gt;Now start up 3D mode on &lt;a href="http://maps.live.com/" class="" mce_href="http://maps.live.com/"&gt;maps.live.com&lt;/a&gt;&amp;nbsp;and you should see a notification upon startup from the hello world plugin.&lt;/p&gt;
&lt;p&gt;&lt;img src="http://kristoffer.members.winisp.net/Images/VirtualEarth3DPlugins/HelloWorldFromPlugin.png" style="width: 874px; height: 704px;" mce_src="http://kristoffer.members.winisp.net/Images/VirtualEarth3DPlugins/HelloWorldFromPlugin.png" border="0" height="704" width="874"&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;That's it for creating a simple plugin. If you want to explore further on your own the Host object contains all the interfaces for a plugin to communicate with VE3D.&lt;/p&gt;&lt;p&gt;Mandatory disclaimer so I don't get into trouble: creating plugins is not officially supported.&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=6178675" width="1" height="1"&gt;</content><author><name>Kristoffer</name><uri>http://blogs.msdn.com/members/Kristoffer.aspx</uri></author><category term="Virtual Earth 3D" scheme="http://blogs.msdn.com/kristoffer/archive/tags/Virtual+Earth+3D/default.aspx" /><category term="Virtual Earth 3D Plugins" scheme="http://blogs.msdn.com/kristoffer/archive/tags/Virtual+Earth+3D+Plugins/default.aspx" /></entry><entry><title>Is your e-mail going unanswered?</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/kristoffer/archive/2007/06/29/is-your-e-mail-going-unanswered.aspx" /><id>http://blogs.msdn.com/kristoffer/archive/2007/06/29/is-your-e-mail-going-unanswered.aspx</id><published>2007-06-29T18:00:00Z</published><updated>2007-06-29T18:00:00Z</updated><content type="html">&lt;p&gt;As a general rule the chance of your e-mail getting a response is inversely proportional to the number of people on the To and Cc lines.&lt;/p&gt; &lt;p&gt;Let's take an example:&lt;/p&gt; &lt;blockquote&gt; &lt;p&gt;You e-mail Bob a question. Bob now feels directly responsible for your question and promptly replies.&lt;/p&gt; &lt;p&gt;You e-mail Bob, Anna, and Frank a question and put them all on the To line. Now Bob, Anna, and Frank are only one third responsible each&amp;nbsp;for replying and all three ignore your e-mail hoping one of the other two will respond.&lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;Psychologists call this "diffusion of responsibility".&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=3608199" width="1" height="1"&gt;</content><author><name>Kristoffer</name><uri>http://blogs.msdn.com/members/Kristoffer.aspx</uri></author><category term="Office observations" scheme="http://blogs.msdn.com/kristoffer/archive/tags/Office+observations/default.aspx" /></entry><entry><title>Virtual Earth update</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/kristoffer/archive/2007/04/03/virtual-earth-update.aspx" /><id>http://blogs.msdn.com/kristoffer/archive/2007/04/03/virtual-earth-update.aspx</id><published>2007-04-04T01:47:00Z</published><updated>2007-04-04T01:47:00Z</updated><content type="html">Virtual Earth released a new version this afternoon; read about the new features on the &lt;a href="http://virtualearth.spaces.live.com/blog/cns%212BBC66E99FDCDB98%218495.entry" mce_href="http://virtualearth.spaces.live.com/blog/cns!2BBC66E99FDCDB98!8495.entry"&gt;Virtual Earth blog&lt;/a&gt;.&lt;br&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=2022535" width="1" height="1"&gt;</content><author><name>Kristoffer</name><uri>http://blogs.msdn.com/members/Kristoffer.aspx</uri></author><category term="Virtual Earth" scheme="http://blogs.msdn.com/kristoffer/archive/tags/Virtual+Earth/default.aspx" /></entry><entry><title>Visual Studio Tip: Examining long strings while debugging</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/kristoffer/archive/2007/04/03/visual-studio-tip-examining-long-strings-while-debugging.aspx" /><id>http://blogs.msdn.com/kristoffer/archive/2007/04/03/visual-studio-tip-examining-long-strings-while-debugging.aspx</id><published>2007-04-03T16:53:23Z</published><updated>2007-04-03T16:53:23Z</updated><content type="html">&lt;p&gt;Long strings can be a pain to examine in Visual Studio while you're debugging but in .NET projects&amp;nbsp;you can easily write these to a file on the fly. If for example we want to examine the contents of string &lt;strong&gt;s&lt;/strong&gt;, open up the &lt;strong&gt;Immediate Window&lt;/strong&gt; (&lt;strong&gt;Ctrl+I&lt;/strong&gt;) and type &lt;pre&gt;&lt;strong&gt;System.IO.File.WriteAllText("C:\\Debug.txt", s);&lt;/strong&gt;&lt;/pre&gt;
&lt;p&gt;Then open up C:\Debug.txt to see the entire string.&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=2019349" width="1" height="1"&gt;</content><author><name>Kristoffer</name><uri>http://blogs.msdn.com/members/Kristoffer.aspx</uri></author><category term="Visual Studio" scheme="http://blogs.msdn.com/kristoffer/archive/tags/Visual+Studio/default.aspx" /></entry><entry><title>Navigate large solutions in Visual Studio quicker</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/kristoffer/archive/2007/03/23/navigate-large-solutions-in-visual-studio-quicker.aspx" /><id>http://blogs.msdn.com/kristoffer/archive/2007/03/23/navigate-large-solutions-in-visual-studio-quicker.aspx</id><published>2007-03-23T16:25:57Z</published><updated>2007-03-23T16:25:57Z</updated><content type="html">&lt;p&gt;The one Visual Studio tip that everyone should know is how to quickly open a file in a large solution without having to remember which folder or project it's in.&lt;/p&gt; &lt;p&gt;Press &lt;strong&gt;Ctrl+Alt+A&lt;/strong&gt; to open up the Command Window, then type &lt;strong&gt;open&lt;/strong&gt; and the first few letters of the filename and you'll get a dropdown of all matching files in the current solution. Press Enter to open the selected file.&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=1938281" width="1" height="1"&gt;</content><author><name>Kristoffer</name><uri>http://blogs.msdn.com/members/Kristoffer.aspx</uri></author><category term="Visual Studio" scheme="http://blogs.msdn.com/kristoffer/archive/tags/Visual+Studio/default.aspx" /></entry><entry><title>Javascript prototype versus closure execution speed</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/kristoffer/archive/2007/02/13/javascript-prototype-versus-closure-execution-speed.aspx" /><id>http://blogs.msdn.com/kristoffer/archive/2007/02/13/javascript-prototype-versus-closure-execution-speed.aspx</id><published>2007-02-13T16:49:12Z</published><updated>2007-02-13T16:49:12Z</updated><content type="html">&lt;p&gt;When Javascript&amp;nbsp;execution speed matters consider using prototype instead of closures where possible. Even for a small closure the difference can be noticable when called hundreds of times. Consider the following example that implements a Pixel object with some ancillary functions in both the closure and prototype patterns:&lt;/p&gt; &lt;div style="font-size: 10pt; background: white; color: black; font-family: courier new"&gt; &lt;p style="margin: 0px"&gt;&lt;span style="color: green"&gt;// Closure implementation&lt;/span&gt;&lt;/p&gt; &lt;p style="margin: 0px"&gt;&lt;span style="color: blue"&gt;function&lt;/span&gt; Pixel(x, y)&lt;/p&gt; &lt;p style="margin: 0px"&gt;{&lt;/p&gt; &lt;p style="margin: 0px"&gt;&amp;nbsp; &lt;span style="color: blue"&gt;this&lt;/span&gt;.x = x;&lt;/p&gt; &lt;p style="margin: 0px"&gt;&amp;nbsp; &lt;span style="color: blue"&gt;this&lt;/span&gt;.y = y;&lt;/p&gt; &lt;p style="margin: 0px"&gt;&amp;nbsp; &lt;span style="color: blue"&gt;this&lt;/span&gt;.getX = &lt;span style="color: blue"&gt;function&lt;/span&gt;()&lt;/p&gt; &lt;p style="margin: 0px"&gt;&amp;nbsp; {&lt;/p&gt; &lt;p style="margin: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue"&gt;return&lt;/span&gt; &lt;span style="color: blue"&gt;this&lt;/span&gt;.x;&lt;/p&gt; &lt;p style="margin: 0px"&gt;&amp;nbsp; }&lt;/p&gt; &lt;p style="margin: 0px"&gt;&amp;nbsp; &lt;span style="color: blue"&gt;this&lt;/span&gt;.getY = &lt;span style="color: blue"&gt;function&lt;/span&gt;()&lt;/p&gt; &lt;p style="margin: 0px"&gt;&amp;nbsp; {&lt;/p&gt; &lt;p style="margin: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue"&gt;return&lt;/span&gt; &lt;span style="color: blue"&gt;this&lt;/span&gt;.y;&lt;/p&gt; &lt;p style="margin: 0px"&gt;&amp;nbsp; }&lt;/p&gt; &lt;p style="margin: 0px"&gt;&amp;nbsp; &lt;span style="color: blue"&gt;this&lt;/span&gt;.setX = &lt;span style="color: blue"&gt;function&lt;/span&gt;(value)&lt;/p&gt; &lt;p style="margin: 0px"&gt;&amp;nbsp; {&lt;/p&gt; &lt;p style="margin: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue"&gt;this&lt;/span&gt;.x = value;&lt;/p&gt; &lt;p style="margin: 0px"&gt;&amp;nbsp; }&lt;/p&gt; &lt;p style="margin: 0px"&gt;&amp;nbsp; &lt;span style="color: blue"&gt;this&lt;/span&gt;.setY = &lt;span style="color: blue"&gt;function&lt;/span&gt;(value)&lt;/p&gt; &lt;p style="margin: 0px"&gt;&amp;nbsp; {&lt;/p&gt; &lt;p style="margin: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue"&gt;this&lt;/span&gt;.y = value;&lt;/p&gt; &lt;p style="margin: 0px"&gt;&amp;nbsp; }&lt;/p&gt; &lt;p style="margin: 0px"&gt;}&lt;/p&gt; &lt;p style="margin: 0px"&gt;&amp;nbsp;&lt;/p&gt; &lt;div style="font-size: 10pt; background: white; color: black; font-family: courier new"&gt; &lt;p style="margin: 0px"&gt;&lt;span style="color: green"&gt;// Prototype implementation&lt;/span&gt;&lt;/p&gt; &lt;p style="margin: 0px"&gt;&lt;span style="color: blue"&gt;function&lt;/span&gt; PixelP(x, y)&lt;/p&gt; &lt;p style="margin: 0px"&gt;{&lt;/p&gt; &lt;p style="margin: 0px"&gt;&amp;nbsp; &lt;span style="color: blue"&gt;this&lt;/span&gt;.x = x; &lt;/p&gt; &lt;p style="margin: 0px"&gt;&amp;nbsp; &lt;span style="color: blue"&gt;this&lt;/span&gt;.y = y;&lt;/p&gt; &lt;p style="margin: 0px"&gt;}&lt;/p&gt; &lt;p style="margin: 0px"&gt;PixelP.prototype.getX = &lt;span style="color: blue"&gt;function&lt;/span&gt;()&lt;/p&gt; &lt;p style="margin: 0px"&gt;{&lt;/p&gt; &lt;p style="margin: 0px"&gt;&amp;nbsp; &lt;span style="color: blue"&gt;return&lt;/span&gt; &lt;span style="color: blue"&gt;this&lt;/span&gt;.x;&lt;/p&gt; &lt;p style="margin: 0px"&gt;}&lt;/p&gt; &lt;p style="margin: 0px"&gt;PixelP.prototype.getY = &lt;span style="color: blue"&gt;function&lt;/span&gt;()&lt;/p&gt; &lt;p style="margin: 0px"&gt;{&lt;/p&gt; &lt;p style="margin: 0px"&gt;&amp;nbsp; &lt;span style="color: blue"&gt;return&lt;/span&gt; &lt;span style="color: blue"&gt;this&lt;/span&gt;.y;&lt;/p&gt; &lt;p style="margin: 0px"&gt;}&lt;/p&gt; &lt;p style="margin: 0px"&gt;PixelP.prototype.setX = &lt;span style="color: blue"&gt;function&lt;/span&gt;(value)&lt;/p&gt; &lt;p style="margin: 0px"&gt;{&lt;/p&gt; &lt;p style="margin: 0px"&gt;&amp;nbsp; &lt;span style="color: blue"&gt;this&lt;/span&gt;.x = value;&lt;/p&gt; &lt;p style="margin: 0px"&gt;}&lt;/p&gt; &lt;p style="margin: 0px"&gt;PixelP.prototype.setY = &lt;span style="color: blue"&gt;function&lt;/span&gt;(value)&lt;/p&gt; &lt;p style="margin: 0px"&gt;{&lt;/p&gt; &lt;p style="margin: 0px"&gt;&amp;nbsp; &lt;span style="color: blue"&gt;this&lt;/span&gt;.y = value;&lt;/p&gt; &lt;p style="margin: 0px"&gt;}&lt;/p&gt; &lt;p style="margin: 0px"&gt;&amp;nbsp;&lt;/p&gt; &lt;p style="margin: 0px"&gt;&amp;nbsp;&lt;/p&gt; &lt;div style="font-size: 10pt; background: white; color: black; font-family: courier new"&gt; &lt;p style="margin: 0px"&gt;&lt;span style="color: blue"&gt;function&lt;/span&gt; TestPerformance()&lt;/p&gt; &lt;p style="margin: 0px"&gt;{&lt;/p&gt; &lt;p style="margin: 0px"&gt;&amp;nbsp; &lt;span style="color: blue"&gt;var&lt;/span&gt; closureStartDateTime = &lt;span style="color: blue"&gt;new&lt;/span&gt; Date();&lt;/p&gt; &lt;p style="margin: 0px"&gt;&amp;nbsp; &lt;span style="color: blue"&gt;for&lt;/span&gt; (&lt;span style="color: blue"&gt;var&lt;/span&gt; i = 0; i &amp;lt; 20000; i++)&lt;/p&gt; &lt;p style="margin: 0px"&gt;&amp;nbsp; {&lt;/p&gt; &lt;p style="margin: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue"&gt;var&lt;/span&gt; x = &lt;span style="color: blue"&gt;new&lt;/span&gt; Pixel(i, i);&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/p&gt; &lt;p style="margin: 0px"&gt;&amp;nbsp; }&lt;/p&gt; &lt;p style="margin: 0px"&gt;&amp;nbsp; &lt;span style="color: blue"&gt;var&lt;/span&gt; closureEndDateTime = &lt;span style="color: blue"&gt;new&lt;/span&gt; Date();&lt;/p&gt; &lt;p style="margin: 0px"&gt;&amp;nbsp;&lt;/p&gt; &lt;p style="margin: 0px"&gt;&amp;nbsp; &lt;span style="color: blue"&gt;var&lt;/span&gt; prototypeStartDateTime = &lt;span style="color: blue"&gt;new&lt;/span&gt; Date();&lt;/p&gt; &lt;p style="margin: 0px"&gt;&amp;nbsp; &lt;span style="color: blue"&gt;for&lt;/span&gt; (&lt;span style="color: blue"&gt;var&lt;/span&gt; i = 0; i &amp;lt; 20000; i++)&lt;/p&gt; &lt;p style="margin: 0px"&gt;&amp;nbsp; {&lt;/p&gt; &lt;p style="margin: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue"&gt;var&lt;/span&gt; x = &lt;span style="color: blue"&gt;new&lt;/span&gt; PixelP(i, i);&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/p&gt; &lt;p style="margin: 0px"&gt;&amp;nbsp; }&lt;/p&gt; &lt;p style="margin: 0px"&gt;&amp;nbsp; &lt;span style="color: blue"&gt;var&lt;/span&gt; prototypeEndDateTime = &lt;span style="color: blue"&gt;new&lt;/span&gt; Date();&lt;/p&gt; &lt;p style="margin: 0px"&gt;&amp;nbsp; &lt;span style="color: blue"&gt;var&lt;/span&gt; closureTime = closureEndDateTime.getTime() - closureStartDateTime.getTime();&lt;/p&gt; &lt;p style="margin: 0px"&gt;&amp;nbsp; &lt;span style="color: blue"&gt;var&lt;/span&gt; prototypeTime = prototypeEndDateTime.getTime() - prototypeStartDateTime.getTime();&lt;/p&gt; &lt;p style="margin: 0px"&gt;&amp;nbsp; alert(&lt;span style="color: #a31515"&gt;"Closure time: "&lt;/span&gt; + closureTime + &lt;span style="color: #a31515"&gt;", prototype time: "&lt;/span&gt; + prototypeTime);&lt;/p&gt; &lt;p style="margin: 0px"&gt;}&lt;/p&gt;&lt;/div&gt;&lt;!--EndFragment--&gt;&lt;/div&gt;&lt;!--EndFragment--&gt;&lt;/div&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;When this is run in IE7 on my machine, the closure implementation takes around 450ms and prototype takes around 140ms. Add two more empty functions and the closure time increases to 560ms and prototype to 155ms.&lt;/p&gt; &lt;p&gt;On Firefox 1.5.0.9 the difference is in the listed example is even larger with the closure taking 515ms and prototype still around 140ms. &lt;/p&gt; &lt;p&gt;For small applications that don't construct hundreds or thousands of the same type of object the execution speed difference between closure and prototype probably doesn't matter so as with all performance advice measure, measure, measure.&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=1670057" width="1" height="1"&gt;</content><author><name>Kristoffer</name><uri>http://blogs.msdn.com/members/Kristoffer.aspx</uri></author><category term="Javascript performance" scheme="http://blogs.msdn.com/kristoffer/archive/tags/Javascript+performance/default.aspx" /></entry><entry><title>Debugging memory usage in managed code using Windbg</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/kristoffer/archive/2007/01/09/debugging-memory-usage-in-managed-code-using-windbg.aspx" /><id>http://blogs.msdn.com/kristoffer/archive/2007/01/09/debugging-memory-usage-in-managed-code-using-windbg.aspx</id><published>2007-01-09T17:08:00Z</published><updated>2007-01-09T17:08:00Z</updated><content type="html">&lt;p&gt;Windbg, is there anything it can't do?&lt;/p&gt; &lt;p&gt;&lt;a href="http://www.microsoft.com/downloads/details.aspx?familyid=a362781c-3870-43be-8926-862b40aa0cd0&amp;amp;displaylang=en" mce_href="http://www.microsoft.com/downloads/details.aspx?familyid=a362781c-3870-43be-8926-862b40aa0cd0&amp;amp;displaylang=en"&gt;CLR Profiler&lt;/a&gt; is great for getting an overview of memory allocations and usage for managed applications but it doesn't work for very large applications and can't be attached after the application has been running for a while to determine why after 12 hours memory use spikes. Windbg can be an acceptable alternative when you find yourself looking at an unexpected memory spike and you're curious where all that memory is being allocated.&lt;/p&gt; &lt;p&gt;Start Windbg, attach to the process, and load the sos dll (&lt;a href="http://blogs.msdn.com/kristoffer/archive/2006/12/29/getting-started-with-windbg-and-managed-code.aspx" mce_href="http://blogs.msdn.com/kristoffer/archive/2006/12/29/getting-started-with-windbg-and-managed-code.aspx"&gt;see previous post&lt;/a&gt;).&lt;/p&gt; &lt;p&gt;We start out by getting a summary of our memory allocations with !dumpheap&lt;/p&gt;&lt;div class="WindbgOutput" style="white-space: pre;"&gt;0:004&amp;gt; !dumpheap -stat total 8952 objects Statistics:&lt;br&gt;       MT    Count    TotalSize Class Name &lt;br&gt;7b4779b8        1           12 System.Windows.Forms.OSFeature &lt;br&gt;7b475ca8        1           12 System.Windows.Forms.FormCollection &lt;br&gt;7b474f8c        1           12 System.Windows.Forms.Layout.DefaultLayout &lt;br&gt;7b4749e0        1           12 System.Windows.Forms.ClientUtils+WeakRefCollection &lt;br&gt;79128f18        1           12 System.Collections.Generic.GenericEqualityComparer`1[[System.Int16, mscorlib]] &lt;br&gt;79128b94        1           12 System.Collections.Generic.ObjectEqualityComparer`1[[System.IntPtr, mscorlib]] &lt;br&gt;79127ae4        1           12 System.Collections.Generic.ObjectEqualityComparer`1[[System.Object, mscorlib]] &lt;br&gt;79114408        1           12 System.Security.Permissions.ReflectionPermission &lt;br&gt;791142e8        1           12 System.Security.Permissions.FileDialogPermission &lt;br&gt;----------------- snip ---------------------- &lt;br&gt;790fd4ec       82         1968 System.Version &lt;br&gt;7ae76b24      208         2496 System.Drawing.KnownColor &lt;br&gt;791242ec       20         2952 System.Collections.Hashtable+bucket[] &lt;br&gt;79114bf0      181         5068 System.Security.SecurityElement &lt;br&gt;791036b0      229         5496 System.Collections.ArrayList &lt;br&gt;00155a48       50        23424      Free &lt;br&gt;79124228      306        47780 System.Object[] &lt;br&gt;790fa3e0     6662       379600 System.String &lt;br&gt;79124418        9      3156304 &lt;b&gt;System.Byte[]&lt;/b&gt; Total 8952 objects&lt;/div&gt; &lt;p&gt;We've got about 3 megs worth of System.Byte[] allocated so let's focus in on this to see why these objects exist.&lt;/p&gt;&lt;div class="WindbgOutput" style="white-space: pre;"&gt;0:004&amp;gt; !dumpheap -type &lt;b&gt;System.Byte[]&lt;/b&gt; &lt;br&gt;&amp;nbsp;Address       MT     Size &lt;br&gt;01241e5c 79124418       12      &lt;br&gt;0124aaf4 79124418       28      &lt;br&gt;0124ab48 79124418      140      &lt;br&gt;01251178 79124418      172      &lt;br&gt;0125129c 79124418       28      &lt;br&gt;01254f7c 79124418    10148      &lt;br&gt;&lt;b&gt;02246da8&lt;/b&gt; 79124418  1048592      &lt;br&gt;02346db8 79124418  1048592      &lt;br&gt;02446dc8 79124418  1048592      &lt;br&gt;total 9 objects &lt;br&gt;Statistics:       MT    Count    TotalSize Class Name &lt;br&gt;79124418        9      3156304 System.Byte[] &lt;br&gt;Total 9 objects&lt;/div&gt; &lt;p&gt;A few small Byte arrays but 3 of them are a meg each so let's find out why the first object is still alive (or if it is alive at all, a GC might not have happened to collect it yet).&lt;/p&gt;&lt;div class="WindbgOutput" style="white-space: pre;"&gt;0:004&amp;gt; !gcroot &lt;b&gt;02246da8&lt;/b&gt; &lt;br&gt;Note: Roots found on stacks may be false positives. Run "!help gcroot" for more info. &lt;br&gt;ebx:Root:012525d8(System.Windows.Forms.Application+ThreadContext)-&amp;gt; &lt;br&gt;01251d58(WindbgDemo.Form1)-&amp;gt; &lt;br&gt;01251edc(System.Collections.ArrayList)-&amp;gt; &lt;br&gt;0125c278(System.Object[])-&amp;gt; &lt;br&gt;02246da8(System.Byte[]) &lt;br&gt;Scan Thread 0 OSTHread 1194 &lt;br&gt;Scan Thread 2 OSTHread 1720&lt;/div&gt; &lt;p&gt;The application has a reference to Form1 which has a reference to an ArrayList which has a reference to my Byte array. If a GC were to happen right now this object would be kept alive.&lt;/p&gt; &lt;p&gt;Instead of checking each Byte array by address individually we can use the .foreach token.&lt;/p&gt;&lt;div class="WindbgOutput" style="white-space: pre;"&gt;0:004&amp;gt; .foreach (obj {!dumpheap -type &lt;b&gt;System.Byte[]&lt;/b&gt; -short}) {.echo obj;!gcroot obj} &lt;br&gt;01241e5c &lt;br&gt;Note: Roots found on stacks may be false positives. Run "!help gcroot" for more info. &lt;br&gt;Scan Thread 0 OSTHread 1194 &lt;br&gt;Scan Thread 2 OSTHread 1720 &lt;br&gt;DOMAIN(00149768):HANDLE(Pinned):3e13fc:Root:02241010(System.Object[])-&amp;gt; &lt;br&gt;01241e5c(System.Byte[]) &lt;br&gt;0124aaf4 &lt;br&gt;Note: Roots found on stacks may be false positives. Run "!help gcroot" for more info. &lt;br&gt;Scan Thread 0 OSTHread 1194 &lt;br&gt;Scan Thread 2 OSTHread 1720 &lt;br&gt;DOMAIN(00149768):HANDLE(Pinned):3e13fc:Root:02241010(System.Object[])-&amp;gt; &lt;br&gt;0124a1c4(System.Environment+ResourceHelper)-&amp;gt; &lt;br&gt;0124a358(System.Resources.ResourceManager)-&amp;gt; &lt;br&gt;0124a3a0(System.Collections.Hashtable)-&amp;gt; &lt;br&gt;0124a3d8(System.Collections.Hashtable+bucket[])-&amp;gt; &lt;br&gt;0124a9f8(System.Resources.RuntimeResourceSet)-&amp;gt; &lt;br&gt;0124aa5c(System.Resources.ResourceReader)-&amp;gt; &lt;br&gt;0124aaac(System.IO.BinaryReader)-&amp;gt; &lt;br&gt;0124aaf4(System.Byte[]) &lt;br&gt;0124ab48 &lt;br&gt;Note: Roots found on stacks may be false positives. Run "!help gcroot" for more info. &lt;br&gt;Scan Thread 0 OSTHread 1194 &lt;br&gt;Scan Thread 2 OSTHread 1720 &lt;br&gt;DOMAIN(00149768):HANDLE(Pinned):3e13fc:Root:02241010(System.Object[])-&amp;gt; &lt;br&gt;0124a1c4(System.Environment+ResourceHelper)-&amp;gt; &lt;br&gt;0124a358(System.Resources.ResourceManager)-&amp;gt; &lt;br&gt;0124a3a0(System.Collections.Hashtable)-&amp;gt; &lt;br&gt;0124a3d8(System.Collections.Hashtable+bucket[])-&amp;gt; &lt;br&gt;0124a9f8(System.Resources.RuntimeResourceSet)-&amp;gt; &lt;br&gt;0124aa5c(System.Resources.ResourceReader)-&amp;gt; &lt;br&gt;0124aaac(System.IO.BinaryReader)-&amp;gt; &lt;br&gt;0124ab48(System.Byte[]) &lt;br&gt;--------------- remainder of output snipped --------------&lt;/div&gt; &lt;p&gt;By using the /ps parameter to .foreach (see Windbg help file for details) you can run gcroot on every nth item to get a sample of objects.&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=1439777" width="1" height="1"&gt;</content><author><name>Kristoffer</name><uri>http://blogs.msdn.com/members/Kristoffer.aspx</uri></author><category term="Windbg" scheme="http://blogs.msdn.com/kristoffer/archive/tags/Windbg/default.aspx" /></entry><entry><title>Debugging lock issues in managed code using Windbg</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/kristoffer/archive/2007/01/05/debugging-lock-issues-in-managed-code-using-windbg.aspx" /><id>http://blogs.msdn.com/kristoffer/archive/2007/01/05/debugging-lock-issues-in-managed-code-using-windbg.aspx</id><published>2007-01-05T16:35:00Z</published><updated>2007-01-05T16:35:00Z</updated><content type="html">&lt;p&gt;Windbg can be helpful for locking lock issues in managed code that seem to only happen on client machines when the moon is full and the stars are aligned just right. Windbg is a minimal installation and with managed code doesn't require debug symbols to still be useful.&lt;/p&gt;
&lt;p&gt;For my test scenario I have an application that hangs for 10 seconds at a time once a button is pressed so I start up windbg and break during the hang so I can inspect what's going on. First we check to see what the managed threads are currently running what:&lt;/p&gt;&lt;div class="WindbgOutput" style="white-space: pre;"&gt;0:000&amp;gt; ~*e!clrstack &lt;br&gt;OS Thread Id: 0x123c (0) &lt;br&gt;ESP       EIP      &lt;br&gt;0012eec8 7c82ed54 [GCFrame: 0012eec8]  0012ef98 7c82ed54 [HelperMethodFrame_1OBJ: 0012ef98] &lt;br&gt;System.Threading.Monitor.Enter(System.Object) &lt;br&gt;0012eff0 00cc0381 TestApp.Form1.button1_Click(System.Object, System.EventArgs) &lt;br&gt;0012f02c 7b060a6b System.Windows.Forms.Control.OnClick(System.EventArgs) &lt;br&gt;0012f03c 7b105379 System.Windows.Forms.Button.OnClick(System.EventArgs) &lt;br&gt;0012f048 7b10547f System.Windows.Forms.Button.OnMouseUp(System.Windows.Forms.MouseEventArgs) &lt;br&gt;0012f06c 7b0d02d2 System.Windows.Forms.Control.WmMouseUp(System.Windows.Forms.Message ByRef, System.Windows.Forms.MouseButtons, Int32) &lt;br&gt;0012f0b8 7b072c74 System.Windows.Forms.Control.WndProc(System.Windows.Forms.Message ByRef) &lt;br&gt;0012f0bc 7b0815a6 [InlinedCallFrame: 0012f0bc]  0012f158 7b0814c3 System.Windows.Forms.Button.WndProc(System.Windows.Forms.Message ByRef) &lt;br&gt;0012f160 7b07a72d System.Windows.Forms.Control+ControlNativeWindow.OnMessage(System.Windows.Forms.Message ByRef) &lt;br&gt;0012f164 7b07a706 System.Windows.Forms.Control+ControlNativeWindow.WndProc(System.Windows.Forms.Message ByRef) &lt;br&gt;0012f178 7b07a515 System.Windows.Forms.NativeWindow.Callback(IntPtr, Int32, IntPtr, IntPtr) &lt;br&gt;0012f324 0033216c [NDirectMethodFrameStandalone: 0012f324] System.Windows.Forms.UnsafeNativeMethods.DispatchMessageW(MSG ByRef) &lt;br&gt;0012f334 7b084766 System.Windows.Forms.Application+ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(Int32, Int32, Int32) &lt;br&gt;0012f3d4 7b08432d System.Windows.Forms.Application+ThreadContext.RunMessageLoopInner(Int32, System.Windows.Forms.ApplicationContext) &lt;br&gt;0012f440 7b08416b System.Windows.Forms.Application+ThreadContext.RunMessageLoop(Int32, System.Windows.Forms.ApplicationContext) &lt;br&gt;0012f470 7b0c69fe System.Windows.Forms.Application.Run(System.Windows.Forms.Form) &lt;br&gt;0012f480 00cc00a8 TestApp.Program.Main() &lt;br&gt;0012f69c 79e88f63 [GCFrame: 0012f69c]  &lt;br&gt;OS Thread Id: 0x1408 (1) &lt;br&gt;Unable to walk the managed stack. The current thread is likely not a  &lt;br&gt;managed thread. You can run !threads to get a list of managed threads in &lt;br&gt;the process &lt;br&gt;OS Thread Id: 0xb30 (2) &lt;br&gt;Failed to start stack walk: 80004005 &lt;br&gt;OS Thread Id: 0x161c (3) &lt;br&gt;Unable to walk the managed stack. The current thread is likely not a  &lt;br&gt;managed thread. You can run !threads to get a list of managed threads in &lt;br&gt;the process &lt;br&gt;OS Thread Id: 0x149c (4) &lt;br&gt;ESP       EIP      &lt;br&gt;011ef82c 7c82ed54 [HelperMethodFrame: 011ef82c] System.Threading.Thread.SleepInternal(Int32) &lt;br&gt;011ef880 793d80f5 System.Threading.Thread.Sleep(Int32) &lt;br&gt;011ef884 00cc042d TestApp.Form1.ThreadProc() &lt;br&gt;011ef8b4 793d7a7b System.Threading.ThreadHelper.ThreadStart_Context(System.Object) &lt;br&gt;011ef8bc 793683dd System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object) &lt;br&gt;011ef8d4 793d7b5c System.Threading.ThreadHelper.ThreadStart() &lt;br&gt;011efaf8 79e88f63 [GCFrame: 011efaf8]  &lt;br&gt;OS Thread Id: 0x7e0 (5) &lt;br&gt;Unable to walk the managed stack. The current thread is likely not a  &lt;br&gt;managed thread. You can run !threads to get a list of managed threads in &lt;br&gt;the process &lt;br&gt;OS Thread Id: 0xf94 (6) &lt;br&gt;Unable to walk the managed stack. The current thread is likely not a &lt;br&gt;managed thread. You can run !threads to get a list of managed threads in &lt;br&gt;the process &lt;br&gt;OS Thread Id: 0x5e4 (7) &lt;br&gt;Unable to walk the managed stack. The current thread is likely not a &lt;br&gt;managed thread. You can run !threads to get a list of managed threads in &lt;br&gt;the process&lt;/div&gt;So we've got two managed threads: 0 (the message pumping thread) and 4. Thread 0 is currently in a call to System.Threading.Monitor.Enter which the &lt;b&gt;lock&lt;/b&gt; statement wraps. Let's see what locks are held by the application. &lt;div class="WindbgOutput" style="white-space: pre;"&gt;0:000&amp;gt; !syncblk &lt;br&gt;Index SyncBlock MonitorHeld Recursion Owning Thread Info  SyncBlock Owner    &lt;br&gt;11 001b415c            3         1 001be180  149c   4   &lt;b&gt;012cfdfc&lt;/b&gt; TestApp.Form1 &lt;br&gt;----------------------------- &lt;br&gt;Total           11 &lt;br&gt;CCW             0 &lt;br&gt;RCW             0 &lt;br&gt;ComClassFactory 0 &lt;br&gt;Free            0&lt;/div&gt;So thread 4 (which is currently sleeping) holds a lock on the object at address 012cfdfc. Let's see what type of object this is: &lt;div class="WindbgOutput" style="white-space: pre;"&gt;0:000&amp;gt; !DumpObj -nofields &lt;b&gt;012cfdfc&lt;/b&gt; &lt;br&gt;Name: TestApp.Form1 &lt;br&gt;MethodTable: &lt;b&gt;008f5ac4&lt;/b&gt; &lt;br&gt;EEClass: 008f165c &lt;br&gt;Size: 332(0x14c) bytes &lt;br&gt; (C:\Testing\WindowsApplication17\WindowsApplication17\bin\Debug\WindowsApplication17.exe)&lt;/div&gt;Thread 4 has a lock on the Form. Looking at the stack objects for thread 0 we can see the Form object right before a synchronization context. &lt;div class="WindbgOutput" style="white-space: pre;"&gt;0:000&amp;gt; !dso &lt;br&gt;OS Thread Id: 0x123c (0) &lt;br&gt;ESP/REG  Object   Name &lt;br&gt;0012edd0 012d05f4 System.Windows.Forms.WindowsFormsSynchronizationContext &lt;br&gt;0012ef00 &lt;b&gt;012cfdfc&lt;/b&gt; TestApp.Form1 &lt;br&gt;0012ef54 012f9f1c System.Threading.ThreadStart &lt;br&gt;0012ef58 012f9f3c System.Threading.Thread &lt;br&gt;0012ef64 012f9f1c System.Threading.ThreadStart &lt;br&gt;0012ef6c 012f9f3c System.Threading.Thread &lt;br&gt;0012efac 012cff60 Microsoft.Win32.SafeHandles.SafeWaitHandle &lt;br&gt;0012efd4 012cfdfc TestApp.Form1 &lt;br&gt;0012eff0 012cfdfc TestApp.Form1 &lt;br&gt;0012eff4 012f9f3c System.Threading.Thread &lt;br&gt;0012eff8 012cfdfc TestApp.Form1 &lt;br&gt;0012effc 012ea688 System.Windows.Forms.Button &lt;br&gt;-------------- snip -----------------------&lt;br&gt; 0012f46c 012ec1e0 System.Windows.Forms.ApplicationContext &lt;br&gt;0012f474 012cfdfc TestApp.Form1&lt;/div&gt;We can confirm this by looking at the IL code for TestApp.Form1.button1_Click. &lt;div class="WindbgOutput" style="white-space: pre;"&gt;0:000&amp;gt; !dumpmt -md &lt;b&gt;008f5ac4&lt;/b&gt; &lt;br&gt;EEClass: 008f165c &lt;br&gt;Module: 008f2d5c &lt;br&gt;Name: TestApp.Form1 &lt;br&gt;mdToken: 02000003 &lt;br&gt; (C:\Testing\WindowsApplication17\WindowsApplication17\bin\Debug\WindowsApplication17.exe)&lt;br&gt;BaseSize: 0x14c &lt;br&gt;ComponentSize: 0x0 &lt;br&gt;Number of IFaces in IFaceMap: 15 &lt;br&gt;Slots in VTable: 376 &lt;br&gt;-------------------------------------- &lt;br&gt;MethodDesc Table &lt;br&gt;&amp;nbsp; &amp;nbsp;Entry MethodDesc      JIT Name &lt;br&gt;7b05c298   7b4a5518   PreJIT System.Windows.Forms.Form.ToString() &lt;br&gt;793539c0   7913bd50   PreJIT System.Object.Equals(System.Object) &lt;br&gt;793539b0   7913bd68   PreJIT System.Object.GetHashCode() &lt;br&gt;7a4a6510   7a75bf58   PreJIT System.ComponentModel.Component.Finalize() &lt;br&gt;79361e50   7913dbd8   PreJIT System.MarshalByRefObject.GetLifetimeService() &lt;br&gt;7b0662a4   7b4a5530   PreJIT System.Windows.Forms.Form.OnResizeEnd(System.EventArgs) &lt;br&gt;------------------ snip -----------------&lt;br&gt;008f61d4   008f5a68      JIT TestApp.Form1.InitializeComponent() &lt;br&gt;008f61b0   008f5a70      JIT TestApp.Form1..ctor() &lt;br&gt;008f6cfc   008f5a78      JIT TestApp.Form1.ThreadProc() &lt;br&gt;008f6a54   &lt;b&gt;008f5a80&lt;/b&gt;      JIT TestApp.Form1.button1_Click(System.Object, System.EventArgs) &lt;br&gt;0:000&amp;gt; !dumpil &lt;b&gt;008f5a80&lt;/b&gt; &lt;br&gt;ilAddr = 00402274 &lt;br&gt;IL_0000: nop &lt;br&gt;IL_0001: ldarg.0 &lt;br&gt;IL_0002: ldftn TestApp.Form1::ThreadProc&lt;br&gt;IL_0008: newobj System.Threading.ThreadStart::.ctor &lt;br&gt;IL_000d: newobj System.Threading.Thread::.ctor &lt;br&gt;IL_0012: stloc.0 &lt;br&gt;IL_0013: ldloc.0 &lt;br&gt;IL_0014: callvirt System.Threading.Thread::Start &lt;br&gt;IL_0019: nop &lt;br&gt;IL_001a: ldarg.0 &lt;br&gt;IL_001b: ldfld TestApp.Form1::threadStarted&lt;br&gt;IL_0020: callvirt System.Threading.WaitHandle::WaitOne &lt;br&gt;IL_0025: pop &lt;br&gt;&lt;b&gt;IL_0026: ldarg.0 &lt;br&gt;IL_0027: dup &lt;br&gt;IL_0028: stloc.1 &lt;br&gt;IL_0029: call System.Threading.Monitor::Enter&lt;/b&gt; &lt;br&gt;IL_002e: nop &lt;br&gt;.try&lt;br&gt;{&lt;br&gt;&amp;nbsp; IL_002f: nop &lt;br&gt;&amp;nbsp; IL_0030: nop &lt;br&gt;&amp;nbsp; IL_0031: leave.s IL_003b&lt;br&gt;} // end .try&lt;br&gt;.finally&lt;br&gt;{&lt;br&gt;&amp;nbsp; IL_0033: ldloc.1 &lt;br&gt;&amp;nbsp; IL_0034: call System.Threading.Monitor::Exit &lt;br&gt;&amp;nbsp; IL_0039: nop &lt;br&gt;&amp;nbsp; IL_003a: endfinally &lt;br&gt;} // end .finally&lt;br&gt;IL_003b: nop &lt;br&gt;IL_003c: ldloc.0 &lt;br&gt;IL_003d: callvirt System.Threading.Thread::Join &lt;br&gt;IL_0042: nop &lt;br&gt;IL_0043: ret &lt;br&gt;&lt;/div&gt;Sure enough Form1 is passing itself to System.Threading.Monitor.Enter.&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=1417123" width="1" height="1"&gt;</content><author><name>Kristoffer</name><uri>http://blogs.msdn.com/members/Kristoffer.aspx</uri></author><category term="Windbg" scheme="http://blogs.msdn.com/kristoffer/archive/tags/Windbg/default.aspx" /></entry><entry><title>Debugging exceptions in managed code using Windbg</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/kristoffer/archive/2007/01/03/debugging-exceptions-in-managed-code-using-windbg.aspx" /><id>http://blogs.msdn.com/kristoffer/archive/2007/01/03/debugging-exceptions-in-managed-code-using-windbg.aspx</id><published>2007-01-03T16:04:27Z</published><updated>2007-01-03T16:04:27Z</updated><content type="html">&lt;p&gt;By default Windbg will break for access violations (or null reference exceptions as they're called in managed code). To get Windbg to break for managed exceptions use the sxe command.&lt;/p&gt;&lt;div class="WindbgOutput" style="white-space: pre"&gt;0:004&amp;gt; sxe clr&lt;br&gt;0:004&amp;gt; g&lt;/div&gt; &lt;p&gt;A little while later our program generates a CLR exception and pops into the debugger.&lt;/p&gt;&lt;div class="WindbgOutput" style="white-space: pre"&gt;(17c.1194): CLR exception - code e0434f4d (first chance)&lt;br&gt;First chance exceptions are reported before any exception handling.&lt;br&gt;This exception may be expected and handled.&lt;br&gt;eax=0012eea0 ebx=0014d578 ecx=00000000 edx=00000025 esi=0012ef2c edi=e0434f4d&lt;br&gt;eip=77e55e02 esp=0012ee9c ebp=0012eef0 iopl=0         nv up ei pl nz na po nc&lt;br&gt;cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000202&lt;br&gt;KERNEL32!RaiseException+0x53:&lt;br&gt;77e55e02 5e              pop     esi&lt;/div&gt; &lt;p&gt;This is a first chance exception so this may be expected and handled, as the message helpfully reminds you. Let's find out what caused this exception.&lt;/p&gt;&lt;div class="WindbgOutput" style="white-space: pre"&gt;0:000&amp;gt; !PrintException&lt;br&gt;Exception object: 01289fb0&lt;br&gt;Exception type: System.ArgumentException&lt;br&gt;Message: Value does not fall within the expected range.&lt;br&gt;InnerException: &amp;lt;none&amp;gt;&lt;none&gt;&lt;br&gt;StackTrace (generated):&lt;br&gt;&amp;lt;none&amp;gt;&lt;br&gt;StackTraceString: &amp;lt;none&amp;gt;&lt;br&gt;HResult: 80070057&lt;/div&gt; &lt;p&gt;We can also have a look at the managed stack trace to see where this exception happened.&lt;/p&gt;&lt;div class="WindbgOutput" style="white-space: pre"&gt;0:000&amp;gt; !CLRStack&lt;br&gt;OS Thread Id: 0x1194 (0)&lt;br&gt;ESP       EIP      &lt;br&gt;0012ef78 77e55e02 [HelperMethodFrame: 0012ef78]&lt;br&gt;0012f01c 00cc0795 WindbgDemo.Form1.CauseOtherException()&lt;br&gt;0012f024 00cc075d WindbgDemo.Form1.btnOtherException_Click(System.Object, System.EventArgs)&lt;br&gt;0012f02c 7b060a6b System.Windows.Forms.Control.OnClick(System.EventArgs)&lt;br&gt;0012f03c 7b105379 System.Windows.Forms.Button.OnClick(System.EventArgs) &lt;br&gt;0012f048 7b10547f System.Windows.Forms.Button.OnMouseUp(System.Windows.Forms.MouseEventArgs)&lt;br&gt;0012f06c 7b0d02d2 System.Windows.Forms.Control.WmMouseUp(System.Windows.Forms.Message ByRef, System.Windows.Forms.MouseButtons, Int32)&lt;br&gt;0012f0b8 7b072c74 System.Windows.Forms.Control.WndProc(System.Windows.Forms.Message ByRef)&lt;br&gt;0012f0bc 7b0815a6 [InlinedCallFrame: 0012f0bc] &lt;br&gt;0012f158 7b0814c3 System.Windows.Forms.Button.WndProc(System.Windows.Forms.Message ByRef)&lt;br&gt;0012f160 7b07a72d System.Windows.Forms.Control+ControlNativeWindow.OnMessage(System.Windows.Forms.Message ByRef)&lt;br&gt;0012f164 7b07a706 System.Windows.Forms.Control+ControlNativeWindow.WndProc(System.Windows.Forms.Message ByRef)&lt;br&gt;0012f178 7b07a515 System.Windows.Forms.NativeWindow.Callback(IntPtr, Int32, IntPtr, IntPtr)&lt;br&gt;0012f324 0033216c [NDirectMethodFrameStandalone: 0012f324] System.Windows.Forms.UnsafeNativeMethods.DispatchMessageW(MSG ByRef)&lt;br&gt;0012f334 7b084766 System.Windows.Forms.Application+ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(Int32, Int32, Int32)&lt;br&gt;0012f3d4 7b08432d System.Windows.Forms.Application+ThreadContext.RunMessageLoopInner(Int32, System.Windows.Forms.ApplicationContext)&lt;br&gt;0012f440 7b08416b System.Windows.Forms.Application+ThreadContext.RunMessageLoop(Int32, System.Windows.Forms.ApplicationContext)&lt;br&gt;0012f470 7b0c69fe System.Windows.Forms.Application.Run(System.Windows.Forms.Form)&lt;br&gt;0012f480 00cc0097 WindbgDemo.Program.Main()&lt;br&gt;0012f69c 79e88f63 [GCFrame: 0012f69c]&lt;/div&gt; &lt;p&gt;If we want to get a feel for what sorts of exceptions are generated by our program but not necessarily inspect each one we can tell Windbg to stop on exceptions, print out some information about the exception, and then continue running all without user intervention.&lt;/p&gt;&lt;div class="WindbgOutput" style="white-space: pre"&gt;0:000&amp;gt; sxe -c "!pe;!clrstack;gc" clr&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=1405113" width="1" height="1"&gt;</content><author><name>Kristoffer</name><uri>http://blogs.msdn.com/members/Kristoffer.aspx</uri></author><category term="Windbg" scheme="http://blogs.msdn.com/kristoffer/archive/tags/Windbg/default.aspx" /></entry><entry><title>Setting a breakpoint in managed code using Windbg</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/kristoffer/archive/2007/01/02/setting-a-breakpoint-in-managed-code-using-windbg.aspx" /><id>http://blogs.msdn.com/kristoffer/archive/2007/01/02/setting-a-breakpoint-in-managed-code-using-windbg.aspx</id><published>2007-01-02T16:49:06Z</published><updated>2007-01-02T16:49:06Z</updated><content type="html">&lt;p&gt;One of the great features of managed code is getting call stacks and proper class and member function names without debug symbols. We can examine the methods of a class and set breakpoints based on name.&lt;/p&gt; &lt;p&gt;To see the methods on an object in Windbg we first need to find its method table. We can do this with the !name2ee command which will look up information about a class.&lt;/p&gt;&lt;div class="WindbgOutput" style="white-space: pre"&gt;0:004&amp;gt; !Name2EE *!WindbgDemo.Form1&lt;br&gt;Module: 790c2000 (mscorlib.dll)&lt;br&gt;--------------------------------------&lt;br&gt;Module: 00912380 sortkey.nlp)&lt;br&gt;--------------------------------------&lt;br&gt;Module: 00912010 (sorttbls.nlp)&lt;br&gt;--------------------------------------&lt;br&gt;Module: 008f2d5c (WindbgDemo.exe)&lt;br&gt;Token: 0x02000004&lt;br&gt;MethodTable: &lt;strong&gt;008f5b5c&lt;/strong&gt;&lt;br&gt;EEClass: 008f15dc&lt;br&gt;Name: WindbgDemo.Form1&lt;br&gt;--------------------------------------&lt;br&gt;Module: 7b442000 (System.Windows.Forms.dll)&lt;br&gt;--------------------------------------&lt;br&gt;Module: 7a714000 (System.dll)&lt;br&gt;--------------------------------------&lt;br&gt;Module: 7ae72000 (System.Drawing.dll)&lt;/div&gt; &lt;p&gt;With the method table address we can examine all the methods defined on the object.&lt;/p&gt;&lt;div class="WindbgOutput" style="white-space: pre"&gt;0:004&amp;gt; !DumpMT -MD &lt;strong&gt;008f5b5c&lt;/strong&gt;&lt;br&gt;EEClass: 008f15dc&lt;br&gt;Module: 008f2d5c&lt;br&gt;Name: WindbgDemo.Form1&lt;br&gt;mdToken: 02000004  (C:\Testing\WindbgDemo\WindbgDemo\bin\Release\WindbgDemo.exe)&lt;br&gt;BaseSize: 0x16c&lt;br&gt;ComponentSize: 0x0&lt;br&gt;Number of IFaces in IFaceMap: 15&lt;br&gt;Slots in VTable: 383&lt;br&gt;--------------------------------------&lt;br&gt;MethodDesc Table&lt;br&gt;   Entry MethodDesc      JIT Name&lt;br&gt;7b05c298   7b4a5518   PreJIT System.Windows.Forms.Form.ToString()&lt;br&gt;793539c0   7913bd50   PreJIT System.Object.Equals(System.Object)&lt;br&gt;793539b0   7913bd68   PreJIT System.Object.GetHashCode()&lt;br&gt;7a4a6510   7a75bf58   PreJIT System.ComponentModel.Component.Finalize()&lt;br&gt;79361e50   7913dbd8   PreJIT System.MarshalByRefObject.GetLifetimeService()&lt;br&gt;79360770   7913dbe0   PreJIT System.MarshalByRefObject.InitializeLifetimeService()&lt;br&gt;--------------- snip ----------------&lt;br&gt;7b06621c   7b4a5528   PreJIT System.Windows.Forms.Form.OnResizeBegin(System.EventArgs)&lt;br&gt;7b0662a4   7b4a5530   PreJIT System.Windows.Forms.Form.OnResizeEnd(System.EventArgs)&lt;br&gt;008f62a0   008f5ac8      JIT WindbgDemo.Form1.InitializeComponent()&lt;br&gt;008f627c   008f5ad0      JIT WindbgDemo.Form1..ctor()&lt;br&gt;008f62bc   008f5ad8     NONE WindbgDemo.Form1.btnLockBlock_Click(System.Object, System.EventArgs)&lt;br&gt;008f6249   008f5ae0     NONE WindbgDemo.Form1.LockBlock()&lt;br&gt;008f62d0   008f5ae8     NONE WindbgDemo.Form1.btnException_Click(System.Object, System.EventArgs)&lt;br&gt;008f6251   008f5af0     NONE WindbgDemo.Form1.CauseException()&lt;br&gt;008f630c   008f5af8     NONE WindbgDemo.Form1.btnOtherException_Click(System.Object, System.EventArgs)&lt;br&gt;008f6259   008f5b00     NONE WindbgDemo.Form1.CauseOtherException()&lt;br&gt;008f62e4   008f5b08     NONE WindbgDemo.Form1.btnMemoryGrowth_Click(System.Object, System.EventArgs)&lt;br&gt;008f62f8   &lt;strong&gt;008f5b10&lt;/strong&gt;     NONE WindbgDemo.Form1.btnBreakpoint_Click(System.Object, System.EventArgs)&lt;br&gt;008f6265   008f5b18     NONE WindbgDemo.Form1.Foo()&lt;/div&gt; &lt;p&gt;For the curious we can see whether the function is ngen'ed code or if it has been JITted yet. PreJIT means ngen code, JIT and NONE is whether the function has been JITted or not. From here we can set a breakpoint.&lt;/p&gt;&lt;div class="WindbgOutput" style="white-space: pre"&gt;0:004&amp;gt; !bpmd -md &lt;b&gt;008f5b10&lt;/b&gt; &lt;br&gt;MethodDesc = 008f5b10&lt;br&gt;Adding pending breakpoints...&lt;/div&gt; &lt;p&gt;It's a pending breakpoint because this code has not been jitted yet and thus has no place to put the debug breakpoint. You can also set breakpoints directly by name using !bpmd.&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=1399686" width="1" height="1"&gt;</content><author><name>Kristoffer</name><uri>http://blogs.msdn.com/members/Kristoffer.aspx</uri></author><category term="Windbg" scheme="http://blogs.msdn.com/kristoffer/archive/tags/Windbg/default.aspx" /></entry><entry><title>Getting started with Windbg and managed code</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/kristoffer/archive/2006/12/29/getting-started-with-windbg-and-managed-code.aspx" /><id>http://blogs.msdn.com/kristoffer/archive/2006/12/29/getting-started-with-windbg-and-managed-code.aspx</id><published>2006-12-29T21:51:10Z</published><updated>2006-12-29T21:51:10Z</updated><content type="html">&lt;p&gt;&lt;a href="http://www.microsoft.com/whdc/devtools/debugging/default.mspx"&gt;Windbg&lt;/a&gt; (or wind bag as my friend calls it) is my one stop shop for almost everything debugging related. It's great for finding issues that only happen on a client machine and you don't want a full blown Visual Studio installation mucking up your repro.&lt;/p&gt; &lt;p&gt;With the &lt;strong&gt;sos&lt;/strong&gt; extension Windbg becomes useful at debugging managed code as well. To get started with Windbg and sos fire up Windbg and attach to a managed process. I'm using .Net 2.0 for my development so I need to load the sos dll from the Framework directory (for 1.1 .Net use .load clr10\sos.dll instead) . I can do this with the .loadby command: &lt;div class="WindbgOutput"&gt;0:000&amp;gt; .loadby sos mscorwks&lt;/div&gt; &lt;p&gt;This tells Windbg to load the debugger extension sos.dll from the same directory that the current process has mscorwks.dll loaded from.&lt;br&gt;Next we hit Debug | Go (or F5) and the process is now happily running away. &lt;/p&gt; &lt;p&gt;Once the problem occurs go back to Windbg and press Debug | Break and we can now examine the process state in safety. If at any point you need help with the sos commands, &lt;b&gt;!help&lt;/b&gt; will get you going.&lt;/p&gt; &lt;p&gt;Coming up next week: using Windbg to debug exceptions, deadlocks, and memory problems in managed code.&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=1381372" width="1" height="1"&gt;</content><author><name>Kristoffer</name><uri>http://blogs.msdn.com/members/Kristoffer.aspx</uri></author><category term="Windbg" scheme="http://blogs.msdn.com/kristoffer/archive/tags/Windbg/default.aspx" /></entry></feed>