<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:blogger='http://schemas.google.com/blogger/2008' xmlns:georss='http://www.georss.org/georss' xmlns:gd="http://schemas.google.com/g/2005" xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-7674671342760410218</id><updated>2025-11-07T10:45:40.263-06:00</updated><category term="debugging"/><category term="tools"/><category term="best practices"/><category term="visual studio"/><category term="windbg"/><category term="memory management"/><category term=".net framework"/><category term="IIS"/><category term="anti-pattern"/><category term="debug"/><category term="dispose"/><category term="linq to xml"/><category term="misc"/><category term="performance"/><category term="references"/><category term="sos"/><category term=".net"/><category term=".net 5"/><category term=".net 9"/><category term=".net core"/><category term="CLR"/><category term="Dependency Injection"/><category term="HTTP"/><category term="HttpClient"/><category term="Javascript"/><category term="angular"/><category term="atomization"/><category term="compiled"/><category term="gc"/><category term="microsoft connect"/><category term="mocking"/><category term="patterns"/><category term="pdb"/><category term="release"/><category term="typescript"/><category term="unit testing"/><category term="versioning"/><category term="x64"/><category term="x86"/><title type='text'>The Black Box of .NET</title><subtitle type='html'>C#, Programming, Design, Architecture, and the internals of Microsoft .NET.</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://dave-black.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7674671342760410218/posts/default?redirect=false'/><link rel='alternate' type='text/html' href='http://dave-black.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><link rel='next' type='application/atom+xml' href='http://www.blogger.com/feeds/7674671342760410218/posts/default?start-index=26&amp;max-results=25&amp;redirect=false'/><author><name>Dave Black</name><uri>http://www.blogger.com/profile/11787334586939943513</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEghXqyOIYI80jcRqlgdIPg99-1bldyR6NKQgYGs8Uq_88qc_HNUrHXqM0R_9FvephlqkYzrrmMwMjSs7JV9QVSQAZMlO5hinHcLQrYmcSTRbCS-g4JIfIJaOYteBSxEzGhnZd9T8HJI2sJ86vEVB-Y_6XqfYX3CkdriJnePd8Yrnav-bw/s1600/linked-in-profile-pic-1743640118751.jfif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>28</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-7674671342760410218.post-2922821577410168193</id><published>2025-02-01T14:28:00.003-06:00</published><updated>2025-02-03T13:36:38.676-06:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="HttpClient"/><category scheme="http://www.blogger.com/atom/ns#" term="mocking"/><category scheme="http://www.blogger.com/atom/ns#" term="unit testing"/><title type='text'>Mocking HttpClient in Unit Tests</title><content type='html'>&lt;p&gt;One of the patterns in writing good unit tests is to mock dependencies. This is important so that you only test the functionality within your class and isolate anything that a dependency might perform. This is especially important when your class accesses an external resource. For example, if I have a database or web api that my class depends on, not only do I not want to have a database CRUD operation, or data-mutating web api operation executed, but these resources will not be available during test execution. Acheiving this mocking is often facilitated by Dependency Injection (DI).&lt;/p&gt;

&lt;p&gt;Given the following simplistic/contrived code, how can you mock the &lt;code class=&quot;language-csharp&quot;&gt;HttpClient&lt;/code&gt; dependency?&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-csharp&quot;&gt;public class ClassUnderTest
{
    private readonly HttpClient _httpClient;
    private const string Url = &amp;quot;https://myurl&amp;quot;;

    public ClassUnderTest(HttpClient httpClient)
    {
        _httpClient = httpClient;
    }

    public async Task&amp;lt;Person&amp;gt; GetPersonAsync(int id)
    {
        var response = await _httpClient.GetAsync($&amp;quot;{Url}?id={id}&amp;quot;);
        return await response.Content.ReadFromJsonAsync&amp;lt;Person&amp;gt;();
    }
}

public class Person
{
    public int Id { get; set; }
    public string Name { get; set; }
    public int Age { get; set; }
}&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;First, let&#39;s consider one solution that, though possible, isn&#39;t the best. &lt;code class=&quot;language-csharp&quot;&gt;HttpClient&lt;/code&gt; does not implement an interface. You write your own interface like this:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-csharp&quot;&gt;public interface IHttpHandler
{
    HttpResponseMessage Get(string url);
    HttpResponseMessage Post(string url, HttpContent content);
    Task&amp;lt;HttpResponseMessage&amp;gt; GetAsync(string url);
    Task&amp;lt;HttpResponseMessage&amp;gt; PostAsync(string url, HttpContent content);
}&lt;/code&gt;&lt;/pre&gt; and add a class that implements it. The details of the implementation would be difficult to write in such a way that they are extensible and usable in various scenarios. Fortunately, there are already solutions out there that are freely available to you via Nuget Package. Let&#39;s walk thru a couple of Nuget Packages that I&#39;ve done some POC&#39;s on using &lt;code class=&quot;language-csharp&quot;&gt;xUnit&lt;/code&gt; before deciding on a single solution (&lt;code class=&quot;language-csharp&quot;&gt;Moq.Contrib.HttpClient&lt;/code&gt;). Then I&#39;ll show examples of how you can use each. Note that there are many more abilities to each framework than what I show below; I kept each example succinct for clarity.
&lt;hr/&gt;
&lt;br/&gt;
&lt;h3&gt;Moq (by itself)&lt;/h3&gt;
&lt;p&gt;This is relatively straightforward if you are familiar with using the &lt;a href=&quot;https://github.com/moq/moq4&quot; target=&quot;_blank&quot;&gt;Moq&lt;/a&gt; framework. The &amp;quot;trick&amp;quot; is to mock the &lt;code class=&quot;language-csharp&quot;&gt;HttpMessageHandler&lt;/code&gt; inside of the &lt;code class=&quot;language-csharp&quot;&gt;HttpClient&lt;/code&gt; - not the &lt;code class=&quot;language-csharp&quot;&gt;HttpClient&lt;/code&gt; itself. NOTE: It is good practice to use &lt;code class=&quot;language-csharp&quot;&gt;MockBehavior.Strict&lt;/code&gt; in the mock so that you are alerted to any calls that you have not explicitly mocked-out and were expecting.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Example:&lt;/em&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-csharp&quot;&gt;[Fact]
public async Task JustMoq()
{
    //arrange
    const int personId = 1;
    var mockHandler = new Mock&amp;lt;HttpMessageHandler&amp;gt;(MockBehavior.Strict);
    var dto = new Person { Id = personId, Name = &amp;quot;Dave&amp;quot;, Age = 42 };
    var mockResponse = new HttpResponseMessage
    {
        StatusCode = HttpStatusCode.OK,
        Content = JsonContent.Create&amp;lt;Person&amp;gt;(dto)
    };

    mockHandler
        .Protected()
        .Setup&amp;lt;Task&amp;lt;HttpResponseMessage&amp;gt;&amp;gt;(
            &amp;quot;SendAsync&amp;quot;,
            ItExpr.Is&amp;lt;HttpRequestMessage&amp;gt;(m =&amp;gt; m.Method == HttpMethod.Get),
            ItExpr.IsAny&amp;lt;CancellationToken&amp;gt;())
        .ReturnsAsync(mockResponse);

    // Inject the handler or client into your application code
    var httpClient = new HttpClient(mockHandler.Object);
    var sut = new ClassUnderTest(httpClient);

    //act
    var actual = await sut.GetPersonAsync(personId);

    //assert
    Assert.NotNull(actual);
    mockHandler.Protected().Verify(
        &amp;quot;SendAsync&amp;quot;,
        Times.Exactly(1),
        ItExpr.Is&amp;lt;HttpRequestMessage&amp;gt;(m =&amp;gt; m.Method == HttpMethod.Get),
        ItExpr.IsAny&amp;lt;CancellationToken&amp;gt;());
}&lt;/code&gt;&lt;/pre&gt;

&lt;hr/&gt;
&lt;br/&gt;
&lt;h3&gt;RichardSzalay.MockHttp&lt;/h3&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/richardszalay/mockhttp&quot; target=&quot;_blank&quot;&gt;RichardSzalay.MockHttp&lt;/a&gt; is another popular solution. I&amp;#39;ve used this in the past but found it slightly more cumbersome that &lt;code class=&quot;language-csharp&quot;&gt;Moq.Contrib.HttpClient&lt;/code&gt;. There are two different patterns that can be used here. Richard describes when to use one vs the other &lt;a href=&quot;https://github.com/richardszalay/mockhttp#when-backend-definitions-vs-expect-request-expectations&quot; target=&quot;_blank&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Example (using BackendDefinition pattern):&lt;/em&gt;&lt;p&gt;
&lt;pre&gt;&lt;code class=&quot;language-csharp&quot;&gt;[Fact]
public async Task RichardSzalayMockHttpUsingBackendDefinition()
{
    //arrange
    const int personId = 1;
    using var mockHandler = new MockHttpMessageHandler();
    var dto = new Person { Id = personId, Name = &amp;quot;Dave&amp;quot;, Age = 42 };
    var mockResponse = new HttpResponseMessage
    {
        StatusCode = HttpStatusCode.OK,
        Content = JsonContent.Create&amp;lt;Person&amp;gt;(dto)
    };

    var mockedRequest = mockHandler.When(HttpMethod.Get, &amp;quot;https://myurl?id=1&amp;quot;)
        .Respond(mockResponse.StatusCode, mockResponse.Content);

    // Inject the handler or client into your application code
    var httpClient = mockHandler.ToHttpClient();
    var sut = new ClassUnderTest(httpClient);

    //act
    var actual = await sut.GetPersonAsync(personId);

    //assert
    Assert.NotNull(actual);
    Assert.Equivalent(dto, actual);
    Assert.Equal(1, mockHandler.GetMatchCount(mockedRequest));
    mockHandler.VerifyNoOutstandingRequest();
}&lt;/code&gt;&lt;/pre&gt;  
  
&lt;p&gt;&lt;em&gt;Example (using RequestExpectation pattern):&lt;/em&gt;&lt;p&gt;
&lt;pre&gt;&lt;code class=&quot;language-csharp&quot;&gt;[Fact]
public async Task RichardSzalayMockHttpUsingRequestExpectation()
{
    //arrange
    const int personId = 1;
    using var mockHandler = new MockHttpMessageHandler();
    var dto = new Person { Id = personId, Name = &amp;quot;Dave&amp;quot;, Age = 42 };
    var mockResponse = new HttpResponseMessage
    {
        StatusCode = HttpStatusCode.OK,
        Content = JsonContent.Create&amp;lt;Person&amp;gt;(dto)
    };

    var mockedRequest = mockHandler.Expect(HttpMethod.Get, &amp;quot;https://myurl&amp;quot;)
        .WithExactQueryString($&amp;quot;id={personId}&amp;quot;)
        .Respond(mockResponse.StatusCode, mockResponse.Content);

    // Inject the handler or client into your application code
    var httpClient = mockHandler.ToHttpClient();
    var sut = new ClassUnderTest(httpClient);

    //act
    var actual = await sut.GetPersonAsync(personId);

    //assert
    Assert.NotNull(actual);
    Assert.Equivalent(dto, actual);
    Assert.Equal(1, mockHandler.GetMatchCount(mockedRequest));
    mockHandler.VerifyNoOutstandingExpectation();
}&lt;/code&gt;&lt;/pre&gt;

&lt;hr/&gt;
&lt;br/&gt;
&lt;h3&gt;Moq.Contrib.HttpClient&lt;/h3&gt;
&lt;p&gt;Like the solution for using &lt;code class=&quot;language-csharp&quot;&gt;Moq&lt;/code&gt; by itself, this is straightforward if you are familiar with using the &lt;a href=&quot;https://github.com/moq/moq4&quot; target=&quot;_blank&quot;&gt;Moq&lt;/a&gt; framework. I found this solution to be slightly more direct with less code. This is the solution I opted to use. Note that this solution requires a separate Nuget from &lt;code class=&quot;language-csharp&quot;&gt;Moq&lt;/code&gt; itself - &lt;a href=&quot;https://github.com/maxkagamine/Moq.Contrib.HttpClient&quot; target=&quot;_blank&quot;&gt;Moq.Contrib.HttpClient&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Example:&lt;/em&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-csharp&quot;&gt;[Fact]
public async Task UsingMoqContribHttpClient()
{
    //arrange
    const int personId = 1;
    var mockHandler = new Mock&amp;lt;HttpMessageHandler&amp;gt;(MockBehavior.Strict);
    var dto = new Person { Id = personId, Name = &amp;quot;Dave&amp;quot;, Age = 42 };
    var mockUrl = $&amp;quot;https://myurl?id={personId}&amp;quot;;
    var mockResponse = mockHandler.SetupRequest(HttpMethod.Get, mockUrl)
        .ReturnsJsonResponse&amp;lt;Person&amp;gt;(HttpStatusCode.OK, dto);

    // Inject the handler or client into your application code
    var httpClient = mockHandler.CreateClient();
    var sut = new ClassUnderTest(httpClient);

    //act
    var actual = await sut.GetPersonAsync(personId);

    //assert
    Assert.NotNull(actual);
    Assert.Equivalent(dto, actual);
    mockHandler.VerifyRequest(HttpMethod.Get, mockUrl, Times.Once());
}&lt;/code&gt;&lt;/pre&gt;

&lt;hr/&gt;
&lt;br/&gt;
&lt;h3&gt;WireMock.Net&lt;/h3&gt;
&lt;p&gt;A realtive newcomer to the game, &lt;a href=&quot;https://github.com/WireMock-Net/WireMock.Net/wiki/Using-WireMock-in-UnitTests&quot; target=&quot;_blank&quot;&gt;WireMock.net&lt;/a&gt; is gaining popularity. This would be a reasonable solution instead of &lt;code class=&quot;language-csharp&quot;&gt;Microsoft.AspNetCore.TestHost&lt;/code&gt; if you are writing Integration Tests where calls to the endpoint are actually made instead of being mocked. I thought this would be my pick at first but decided against it for two reasons:&lt;/p&gt;
&lt;ol&gt;
	&lt;li&gt;it does actually open ports to facilitate the test. Since I&amp;#39;ve had to fix &lt;a href=&quot;https://learn.microsoft.com/en-us/dotnet/fundamentals/networking/http/httpclient-guidelines&quot; target=&quot;_blank&quot;&gt;port-exhaustion&lt;/a&gt; issues from improper usage of &lt;code class=&quot;language-csharp&quot;&gt;HttpClient&lt;/code&gt; in the past, I decided to pass on this solution as I wasn&amp;#39;t sure how well it would scale across a large codebase with many unit tests running in parallel.&lt;/li&gt;
	&lt;li&gt;The urls used must be resolvable (actual legit urls). If you want the simplicity of not caring about a &amp;quot;real&amp;quot; url (just that the url you expected was actually called) then this may not be for you.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;em&gt;Example:&lt;/em&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-csharp&quot;&gt;public class TestClass : IDisposable
{
    private WireMockServer _server;

    public TestClass()
    {
        _server = WireMockServer.Start();
    }

    public void Dispose()
    {
        _server.Stop();
    }

    [Fact]
    public async Task UsingWireMock()
    {
        //arrange
        const int personId = 1;
        var dto = new Person { Id = personId, Name = &amp;quot;Dave&amp;quot;, Age = 42 };
        var mockUrl = $&amp;quot;https://myurl?id={personId}&amp;quot;;

        _server.Given(
            Request.Create()
                .WithPath(mockUrl))
            .RespondWith(
                Response.Create()
                    .WithStatusCode(200)
                    .WithHeader(&amp;quot;Content-Type&amp;quot;, &amp;quot;application/json&amp;quot;)
                    .WithBodyAsJson(dto));

        // Inject the handler or client into your application code
        var httpClient = _server.CreateClient();
        var sut = new ClassUnderTest(httpClient);

        //act
        var actual = await sut.GetPersonAsync(personId);

        //assert
        Assert.NotNull(actual);
        Assert.Equivalent(dto, actual);
    }
}&lt;/code&gt;&lt;/pre&gt;
</content><link rel='replies' type='application/atom+xml' href='http://dave-black.blogspot.com/feeds/2922821577410168193/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://dave-black.blogspot.com/2025/02/mocking-httpclient-in-unit-tests.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7674671342760410218/posts/default/2922821577410168193'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7674671342760410218/posts/default/2922821577410168193'/><link rel='alternate' type='text/html' href='http://dave-black.blogspot.com/2025/02/mocking-httpclient-in-unit-tests.html' title='Mocking HttpClient in Unit Tests'/><author><name>Dave Black</name><uri>http://www.blogger.com/profile/11787334586939943513</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEghXqyOIYI80jcRqlgdIPg99-1bldyR6NKQgYGs8Uq_88qc_HNUrHXqM0R_9FvephlqkYzrrmMwMjSs7JV9QVSQAZMlO5hinHcLQrYmcSTRbCS-g4JIfIJaOYteBSxEzGhnZd9T8HJI2sJ86vEVB-Y_6XqfYX3CkdriJnePd8Yrnav-bw/s1600/linked-in-profile-pic-1743640118751.jfif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7674671342760410218.post-3541131557088988672</id><published>2025-01-14T13:33:00.004-06:00</published><updated>2025-02-03T13:38:00.841-06:00</updated><category scheme="http://www.blogger.com/atom/ns#" term=".net 9"/><category scheme="http://www.blogger.com/atom/ns#" term="debugging"/><category scheme="http://www.blogger.com/atom/ns#" term="visual studio"/><title type='text'>.NET 9.0 Debugging Issue - F10 Step Over executes multiple steps</title><content type='html'>I recently ran into a debugging issue with my latest VisualStudio 2022 update and Resharper C# installation. It&#39;s important to note that I didn&#39;t start using this setup until I&#39;d upgraded my projects to .NET 9.0.&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;I was able to hit breakpoints but found that while stepping over statements (F10), the debugger would sometimes run to the next breakpoint, execute a random number of steps forward to a different line in the call stack, or run to completion. The issue was intermittent too. Ugh. I also use a number of VisualStudio extensions so that didn&#39;t make it any easier to find the cause. I ended up trying the following to no avail:
  
&lt;div&gt;&lt;ol style=&quot;text-align: left;&quot;&gt;&lt;li&gt;disabling Resharper&#39;s Async Typing and Debugger Integration. I&#39;d seen some race conditions with the Async Typing and since the debugging issue was intermittent I figured I&#39;d try disabling Async Typing even though it didn&#39;t have any apparent connection to the debugger.&amp;nbsp;&lt;/li&gt;&lt;li&gt;disabling all extensions&amp;nbsp;&lt;/li&gt;&lt;li&gt;uninstalling all extensions&amp;nbsp;&lt;/li&gt;&lt;li&gt;repairing the VisualStudio installation&lt;/li&gt;&lt;/ol&gt;&lt;div&gt;Once I was down to a bare bones VisualStudio installation I figured it was VisualStudio itself. By this time I didn&#39;t want to continue &lt;a href=&quot;https://www.oreilly.com/library/view/the-art-of/9780471469124/9780471469124_debugging_by_deduction.html#:~:text=The%20process%20of%20deduction%20proceeds,the%20location%20of%20the%20error)&quot; target=&quot;_blank&quot;&gt;debugging by deduction&lt;/a&gt; any longer so I didn&#39;t want to go down the road of rolling back to previous VisualStudio versions. I went on to the Feedback Forum for VisualStudio to look for an existing bug and open one if I couldn&#39;t find one there. I came upon this issue in the Developer Forum:&amp;nbsp;&lt;a href=&quot;https://developercommunity.visualstudio.com/t/Debugger-randomly-stepping-over-user-cod/10802237#T-N10816638&quot; target=&quot;_blank&quot;&gt;Debugger randomly stepping over user code&lt;/a&gt;. It never occurred to me that I was now using .NET 9 and the problem could&#39;ve been related.&amp;nbsp;🤯&lt;/div&gt;
  
&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;I ultimately found the following issues opened for the .NET 9.0 runtime which all had the same root cause:&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;ul style=&quot;text-align: left;&quot;&gt;&lt;li&gt;Debugging Issue VS 2022 .net 9 &lt;a href=&quot;https://github.com/dotnet/runtime/issues/110841&quot; target=&quot;_blank&quot;&gt;#110841&lt;/a&gt;&lt;/li&gt;&lt;li&gt;Step becomes a &quot;go&quot; in .NET 9 &lt;a href=&quot;https://github.com/dotnet/runtime/issues/109785&quot; target=&quot;_blank&quot;&gt;#109785&lt;/a&gt;&lt;/li&gt;&lt;li&gt;foreach will jump to other code in dotnet9 &lt;a href=&quot;https://github.com/dotnet/runtime/issues/109812&quot; target=&quot;_blank&quot;&gt;#109812&lt;/a&gt;&lt;/li&gt;&lt;li&gt;Step Over sometimes executes a lot more than one statement &lt;a href=&quot;https://github.com/dotnet/runtime/issues/109885&quot; target=&quot;_blank&quot;&gt;#109885&lt;/a&gt;&lt;/li&gt;&lt;li&gt;And the fix merged here: &lt;a href=&quot;https://github.com/dotnet/runtime/pull/110533/files&quot; target=&quot;_blank&quot;&gt;#110533&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;
  
  &lt;div&gt;The fix was pretty small and there were only two files changed:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The Controller in the CoreClr&#39;s Debugger Execution Engine:&lt;/div&gt;
  &lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/a/AVvXsEgTl4XyuMNrB8P-7brA6DwBkkr5NisbWbcLM8nQzkikZzwQQ1qKDWhV7w7j0uIv19LLWAaF3Z8alPlZQWweP4EIAGQmKiF7h31wHD58qew9H6AsYk0AdSLCNkS7U1R338qEcib8Ryr9ZOZvl7PHw-r-fBtWbqECnANGbxY71D50Ox_fF1ci_uQxS2BbZUM&quot; style=&quot;clear: left; margin-bottom: 1em; margin-right: 1em; text-align: center;&quot;&gt;&lt;img alt=&quot;&quot; data-original-height=&quot;1242&quot; data-original-width=&quot;1247&quot; height=&quot;651&quot; src=&quot;https://blogger.googleusercontent.com/img/a/AVvXsEgTl4XyuMNrB8P-7brA6DwBkkr5NisbWbcLM8nQzkikZzwQQ1qKDWhV7w7j0uIv19LLWAaF3Z8alPlZQWweP4EIAGQmKiF7h31wHD58qew9H6AsYk0AdSLCNkS7U1R338qEcib8Ryr9ZOZvl7PHw-r-fBtWbqECnANGbxY71D50Ox_fF1ci_uQxS2BbZUM=w654-h651&quot; width=&quot;654&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;
  
  And the Thread Suspension class:&lt;/div&gt;&lt;div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/a/AVvXsEgPIQBsyQzDjvnP7FAjuoCKqbeAkDVdXrUKVg-xqUGHQSuMH-IMN905xKVWEnLaWY9fzHTcmlraL9xTfnBXX1naEy7OAf2icbdvVoqIl8Sf-pHbae3aOPIqNR_asYSobK2Ztv32B6ZvJguY4AjRaxBlzufIh3I_pPUK94WRAQQoq5rceT2uOA0FmBMnSeY&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img alt=&quot;&quot; data-original-height=&quot;420&quot; data-original-width=&quot;1467&quot; height=&quot;193&quot; src=&quot;https://blogger.googleusercontent.com/img/a/AVvXsEgPIQBsyQzDjvnP7FAjuoCKqbeAkDVdXrUKVg-xqUGHQSuMH-IMN905xKVWEnLaWY9fzHTcmlraL9xTfnBXX1naEy7OAf2icbdvVoqIl8Sf-pHbae3aOPIqNR_asYSobK2Ztv32B6ZvJguY4AjRaxBlzufIh3I_pPUK94WRAQQoq5rceT2uOA0FmBMnSeY=w670-h193&quot; width=&quot;670&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/a/AVvXsEgCeqRGk0O-2aAj2TNy-4lvhrPEx8KRf8gPv9tJlqtEfkl6TBmBhYJVjSc11a-EI8QkcnPCKubju0ikBTQLoKfVU-ryApSQvWcnFGejzk7IF78tPGFrGEasd3CWkltSNPKZIXdTfUXZbkdwAhIf9LFHVk9P6DRhjeeudVYe3t0YzsNMxkCu_NnC4yQkbMo&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img alt=&quot;&quot; data-original-height=&quot;511&quot; data-original-width=&quot;970&quot; height=&quot;271&quot; src=&quot;https://blogger.googleusercontent.com/img/a/AVvXsEgCeqRGk0O-2aAj2TNy-4lvhrPEx8KRf8gPv9tJlqtEfkl6TBmBhYJVjSc11a-EI8QkcnPCKubju0ikBTQLoKfVU-ryApSQvWcnFGejzk7IF78tPGFrGEasd3CWkltSNPKZIXdTfUXZbkdwAhIf9LFHVk9P6DRhjeeudVYe3t0YzsNMxkCu_NnC4yQkbMo=w514-h271&quot; width=&quot;514&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;
  
  &lt;div&gt;Ironically, as I was writing this post I got an email about .NET 9.0.1 &lt;a href=&quot;https://github.com/dotnet/core/releases/tag/v9.0.1&quot; target=&quot;_blank&quot;&gt;being released&lt;/a&gt;. I couldn&#39;t find any of the issues or the PR for the fix included in the &lt;a href=&quot;https://github.com/dotnet/runtime/releases/tag/v9.0.1&quot; target=&quot;_blank&quot;&gt;Release Notes&lt;/a&gt;. I went back to the &lt;a href=&quot;https://github.com/dotnet/runtime/pull/110533&quot; target=&quot;_blank&quot;&gt;Fix a step that becomes a go #110533 PR notes&lt;/a&gt; and saw that the Milestone for the fix is 9.0.2 (release date TBD). I was disappointed to find that the fix was not included in the .NET 9.0.1 Release but happy that it is coming in the next release of 9.0.2.&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dave-black.blogspot.com/feeds/3541131557088988672/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://dave-black.blogspot.com/2025/01/net-90-debugging-issue-f10-step-over.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7674671342760410218/posts/default/3541131557088988672'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7674671342760410218/posts/default/3541131557088988672'/><link rel='alternate' type='text/html' href='http://dave-black.blogspot.com/2025/01/net-90-debugging-issue-f10-step-over.html' title='.NET 9.0 Debugging Issue - F10 Step Over executes multiple steps'/><author><name>Dave Black</name><uri>http://www.blogger.com/profile/11787334586939943513</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEghXqyOIYI80jcRqlgdIPg99-1bldyR6NKQgYGs8Uq_88qc_HNUrHXqM0R_9FvephlqkYzrrmMwMjSs7JV9QVSQAZMlO5hinHcLQrYmcSTRbCS-g4JIfIJaOYteBSxEzGhnZd9T8HJI2sJ86vEVB-Y_6XqfYX3CkdriJnePd8Yrnav-bw/s1600/linked-in-profile-pic-1743640118751.jfif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/a/AVvXsEgTl4XyuMNrB8P-7brA6DwBkkr5NisbWbcLM8nQzkikZzwQQ1qKDWhV7w7j0uIv19LLWAaF3Z8alPlZQWweP4EIAGQmKiF7h31wHD58qew9H6AsYk0AdSLCNkS7U1R338qEcib8Ryr9ZOZvl7PHw-r-fBtWbqECnANGbxY71D50Ox_fF1ci_uQxS2BbZUM=s72-w654-h651-c" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7674671342760410218.post-4704196423888189057</id><published>2025-01-12T16:26:00.008-06:00</published><updated>2025-02-03T13:38:25.562-06:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="atomization"/><category scheme="http://www.blogger.com/atom/ns#" term="linq to xml"/><category scheme="http://www.blogger.com/atom/ns#" term="performance"/><title type='text'>What is LINQ to Xml Atomization?</title><content type='html'>Atomization is the process that the LINQ to Xml runtime uses to store and reuse string instances. Atomization means that if two XName objects have the same local name, and they&#39;re in the same namespace, they share the same instance.
Likewise, if two XNamespace objects have the same namespace URI, they share the same instance.

This optimizes memory usage and improves performance when comparing for equality of:
&lt;ul&gt;&lt;li&gt;One &lt;code class=&quot;language-csharp&quot;&gt;XName&lt;/code&gt; instance to a different &lt;code class=&quot;language-csharp&quot;&gt;XName&lt;/code&gt; instance&lt;/li&gt;
&lt;li&gt;One &lt;code class=&quot;language-csharp&quot;&gt;XNamespace&lt;/code&gt; instance to a different &lt;code class=&quot;language-csharp&quot;&gt;XNamespace&lt;/code&gt; instance&lt;/li&gt;&lt;/ul&gt;
because the underlying intermediate language only has to compare references instead of string comparisons which would take longer. Being able to take advantage of this requires
that both &lt;code class=&quot;language-csharp&quot;&gt;XName&lt;/code&gt; and &lt;code class=&quot;language-csharp&quot;&gt;XNamespace&lt;/code&gt; implement the equality and inequality operators - which of course they do.
This concept is particularly relevant when working with &lt;code class=&quot;language-csharp&quot;&gt;XElement&lt;/code&gt; and &lt;code class=&quot;language-csharp&quot;&gt;XAttribute&lt;/code&gt; instances, where the same names might appear multiple times.

&lt;code class=&quot;language-csharp&quot;&gt;XName&lt;/code&gt; and &lt;code class=&quot;language-csharp&quot;&gt;XNamespace&lt;/code&gt; also implement the Implicit Operator that converts strings to &lt;code class=&quot;language-csharp&quot;&gt;XName&lt;/code&gt; or &lt;code class=&quot;language-csharp&quot;&gt;XNamespace&lt;/code&gt; instances.
This allows for automatically passing atomized instances as parameters to LINQ to Xml methods which then have better performance because of atomization. For example, this code implicitly passes an &lt;code class=&quot;language-csharp&quot;&gt;XName&lt;/code&gt; (with a value of &quot;x&quot;) to the
&lt;code class=&quot;language-csharp&quot;&gt;Descendants&lt;/code&gt; method:
&lt;pre&gt;&lt;code class=&quot;language-csharp&quot;&gt;var root = new XElement(&quot;root&quot;,
  new XElement(&quot;x&quot;, &quot;1&quot;),
  new XElement(&quot;y&quot;,
    new XElement(&quot;x&quot;, &quot;1&quot;),
    new XElement(&quot;x&quot;, &quot;3&quot;)
  )
);

foreach (var e in root.Descendants(&quot;x&quot;).Where(e =&amp;gt; e.Value == &quot;1&quot;))
{
  ...
}&lt;/code&gt;&lt;/pre&gt;

Atomization is similar to string interning in .NET, where identical string literals are stored only once in memory. When LINQ to Xml processes XML data, it often encounters repeated element and attribute names.
Instead of creating a new string object for each occurrence, it reuses existing string instances. It does this by caching the &lt;code class=&quot;language-csharp&quot;&gt;Name&lt;/code&gt; property in &lt;code class=&quot;language-csharp&quot;&gt;XName&lt;/code&gt; and &lt;code class=&quot;language-csharp&quot;&gt;XNamespace&lt;/code&gt;
in an internal static &lt;code class=&quot;language-csharp&quot;&gt;XHashtable&amp;lt;WeakReference&amp;lt;XNamespace&amp;gt;&amp;gt;&lt;/code&gt;. You can find the source code here:
&lt;ul&gt;&lt;li&gt;&lt;a href=&quot;https://github.com/dotnet/runtime/blob/main/src/libraries/System.Private.Xml.Linq/src/System/Xml/Linq/XNamespace.cs&quot; target=&quot;_blank&quot;&gt;XNamespace&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/dotnet/runtime/blob/main/src/libraries/System.Private.Xml.Linq/src/System/Xml/Linq/XHashtable.cs&quot; target=&quot;_blank&quot;&gt;XHashtable&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;

&lt;h3&gt;Practical Implications&lt;/h3&gt;
So how does atomization affect my application?
&lt;ol&gt;&lt;li&gt;&lt;u&gt;Element and Attribute Names&lt;/u&gt;: When you create elements or attributes using LINQ to Xml, the names are atomized. For example, if you create multiple elements with the same name, LINQ to Xml will store the name only once.&lt;/li&gt;
&lt;li&gt;&lt;u&gt;Namespace Handling&lt;/u&gt;: Atomization also applies to XML namespaces. When you define namespaces in your XML, LINQ to XML ensures that each unique namespace URI is stored only once.&lt;/li&gt;
  &lt;li&gt;&lt;u&gt;Value Atomization&lt;/u&gt;: While element and attribute names are atomized, the values are &lt;em&gt;not&lt;/em&gt; automatically atomized. However, if you&#39;re feeling adventurous and you frequently use the same values, you might consider implementing your own caching mechanism to achieve similar benefits.
Now before you go off and write your own caching mechanism to cache values, consider that the .NET team has done a lot of work ensuring the caching of names is both thread-safe and performant. I&#39;ve never found that I needed to do this though the largest xml documents I&#39;ve had to work with are in
the tens of MB&#39;s. If you&#39;re using much larger xml documents of hundreds of MB&#39;s or even 1 GB+ in size, then you may find this worthwhile.&lt;/li&gt;&lt;/ol&gt;

&lt;h3&gt;Pre-Atomization&lt;/h3&gt;
You might be thinking &quot;..this is great, I can&#39;t do anything to improve performance here!&quot;. But there is. Unfortunately, even though you effectively can pass atomized instances to LINQ to Xml methods, there is a small cost. This is because
the Implicit Operator has to be invoked. You can refer to the Atomization Benchmarks at the end of this post to get the details on some benchmarking I did. In a nutshell, the results show
that pre-atomizing is just over 2x faster. That being said, we are talking about a couple hundred nanoseconds in the context of my test for an element with 3 child alements, each having an attribute and string content. The benefit of pre-atomization becomes much more evident with very large XML documents.
Here is the xml used for test data in the benchmarks:
&lt;pre&gt;&lt;code class=&quot;language-xml&quot;&gt;&amp;lt;aw:Root xmlns:aw=&quot;http://www.adventure-works.com&quot;&amp;gt;
  &amp;lt;aw:Data ID=&quot;1&quot;&amp;gt;4,100,000&amp;lt;/aw:Data&amp;gt;
  &amp;lt;aw:Data ID=&quot;2&quot;&amp;gt;3,700,000&amp;lt;/aw:Data&amp;gt;
  &amp;lt;aw:Data ID=&quot;3&quot;&amp;gt;1,150,000&amp;lt;/aw:Data&amp;gt;
&amp;lt;/aw:Root&amp;gt;&lt;/code&gt;&lt;/pre&gt;

&lt;div&gt;The full code for the benchmarks can be found at this gist: &lt;a href=&quot;https://gist.github.com/udlose/1a5b0338c5fa4e83ec71fb22197396cf&quot; target=&quot;_blank&quot;&gt;Linq to Xml - XName Atomization Benchmark.cs&lt;/a&gt;&lt;/div&gt;&lt;br/&gt;

&lt;h3&gt;Atomization and ReferenceEquals&lt;/h3&gt;

Let&#39;s take a look at &lt;code class=&quot;language-csharp&quot;&gt;XName&lt;/code&gt; as an example. There are two ways to directly create &lt;code class=&quot;language-csharp&quot;&gt;XName&lt;/code&gt; instances:
&lt;ol&gt;
&lt;li&gt;The &lt;code class=&quot;language-csharp&quot;&gt;XName.Get(String)&lt;/code&gt; or &lt;code class=&quot;language-csharp&quot;&gt;XName.Get(String, String)&lt;/code&gt; methods. See &lt;a href=&quot;https://learn.microsoft.com/en-us/dotnet/api/system.xml.linq.xname.get?view=net-9.0&quot; target=&quot;_blank&quot;&gt;here&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;The &lt;code class=&quot;language-csharp&quot;&gt;XNamespace.Addition(XNamespace, String) Operator&lt;/code&gt; method. See &lt;a href=&quot;https://learn.microsoft.com/en-us/dotnet/api/system.xml.linq.xnamespace.op_addition?view=net-9.0&quot; target=&quot;_blank&quot;&gt;here&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;
They are also created indirectly by LINQ to Xml when you create &lt;code class=&quot;language-csharp&quot;&gt;XDocument&lt;/code&gt;, &lt;code class=&quot;language-csharp&quot;&gt;XElement&lt;/code&gt;, and &lt;code class=&quot;language-csharp&quot;&gt;XAttribute&lt;/code&gt; instances.
Here is some code to demonstrate that there is a single atomized instance referred to regardless of how the instance was created.

&lt;pre&gt;&lt;code class=&quot;language-csharp&quot;&gt;// Note that these are not explicitly declared as const
string x = &quot;element&quot;;
string y = &quot;element&quot;;
var stringsHaveSameReference = object.ReferenceEquals(x, y);
Console.WriteLine(
  $&quot;string &#39;x&#39; has same reference as string &#39;y&#39; (expect true): {stringsHaveSameReference}&quot;);

// Create new XName instances (indirectly) thru XElement ctor
// using a string as the name
var xNameViaGet1 = XName.Get(localName, namespaceUri);
var xNameViaGet2 = XName.Get(localName, namespaceUri);

// Check if XName instances are the same
namesHaveSameReference = object.ReferenceEquals(xNameViaGet1, xNameViaGet2);
Console.WriteLine($&quot;xNameViaGet1 is same reference as xNameViaGet2 (expect true): {namesHaveSameReference}&quot;);

// Create XName instances via XNamespace.Addition Operator
XNamespace ns = namespaceUri;
XName xNameViaNSAddition1 = ns + localName;
XName xNameViaNSAddition2 = ns + localName;

// Check if XName instances are the same
namesHaveSameReference = object.ReferenceEquals(xNameViaNSAddition1, xNameViaNSAddition2);
Console.WriteLine(
  $&quot;xNameViaNSAddition1 is same reference as xNameViaNSAddition2 (expect true): {namesHaveSameReference}&quot;);

// Create XElement and XAttribute using XName instances
XElement ele = new XElement(xNameViaGet1, &quot;value1&quot;);
XAttribute attr = new XAttribute(xNameViaGet2, &quot;value2&quot;);

// Check if XName instances in XElement and XAttribute are the same
namesHaveSameReference = object.ReferenceEquals(ele.Name, attr.Name);
Console.WriteLine(
  $&quot;ele.Name is same reference as attr.Name (expect true): {namesHaveSameReference}&quot;);

// Compare XName references that were created differently
namesHaveSameReference = object.ReferenceEquals(xNameViaGet1, xNameViaNSAddition1);
Console.WriteLine(
  $&quot;xNameViaGet1 is same reference as xNameViaNSAddition1 (expect true): {namesHaveSameReference}&quot;);
namesHaveSameReference = object.ReferenceEquals(xNameViaGet1, ele.Name);
Console.WriteLine(
  $&quot;xNameViaGet1 is same reference as ele.Name (expect true): {namesHaveSameReference}&quot;);

// Create 2 XElement instances with the same name of &#39;root&#39; and same value
XElement eleViaCtor = new XElement(&quot;root&quot;, &quot;value&quot;);
XElement eleViaParse = XElement.Parse(&quot;&amp;lt;root&amp;gt;value&amp;lt;/root&amp;gt;&quot;);

// Note that the 2 XElements DO NOT have the same reference
bool xelementsHaveSameReference = object.ReferenceEquals(eleViaCtor, eleViaParse);
Console.WriteLine(
  $&quot;eleViaCtor and eleViaParse refer to same instance: {xelementsHaveSameReference}&quot;);

// However, their respective XName properties DO have the same reference
namesHaveSameReference = object.ReferenceEquals(eleViaCtor.Name, eleViaParse.Name);
Console.WriteLine($&quot;eleViaCtor.Name and eleViaParse.Name refer to same instance: {namesHaveSameReference}&quot;);&lt;/code&gt;&lt;/pre&gt;




&lt;h3&gt;Atomization Benchmarks&lt;/h3&gt;
These tests compared creating &lt;code class=&quot;language-csharp&quot;&gt;XElement&lt;/code&gt; and &lt;code class=&quot;language-csharp&quot;&gt;XAttribute&lt;/code&gt; instances by either passing a string or an &lt;code class=&quot;language-csharp&quot;&gt;XName&lt;/code&gt; instance
to the constructors. Note that the memory allocations were identicial since they are all referring to the same &lt;code class=&quot;language-csharp&quot;&gt;XName&lt;/code&gt; instance.
&lt;pre&gt;Method                            | Mean     | Error   | StdDev  | Ratio | Gen0   | Allocated | Alloc Ratio |
----------------------------------|---------:|--------:|--------:|------:|-------:|----------:|------------:|
XNode_Construction_Passing_Strings| 355.9 ns | 3.69 ns | 3.45 ns |  1.00 | 0.0391 |     656 B |        1.00 |
XNode_Construction_Passing_XName  | 136.0 ns | 1.95 ns | 1.82 ns |  0.38 | 0.0391 |     656 B |        1.00 |
&lt;/pre&gt;

The full code for the benchmarks can be found at this gist: &lt;a href=&quot;https://gist.github.com/udlose/1a5b0338c5fa4e83ec71fb22197396cf&quot; target=&quot;_blank&quot;&gt;Linq to Xml - XName Atomization Benchmark.cs&lt;/a&gt;</content><link rel='replies' type='application/atom+xml' href='http://dave-black.blogspot.com/feeds/4704196423888189057/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://dave-black.blogspot.com/2025/01/what-is-linq-to-xml-atomization.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7674671342760410218/posts/default/4704196423888189057'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7674671342760410218/posts/default/4704196423888189057'/><link rel='alternate' type='text/html' href='http://dave-black.blogspot.com/2025/01/what-is-linq-to-xml-atomization.html' title='What is LINQ to Xml Atomization?'/><author><name>Dave Black</name><uri>http://www.blogger.com/profile/11787334586939943513</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEghXqyOIYI80jcRqlgdIPg99-1bldyR6NKQgYGs8Uq_88qc_HNUrHXqM0R_9FvephlqkYzrrmMwMjSs7JV9QVSQAZMlO5hinHcLQrYmcSTRbCS-g4JIfIJaOYteBSxEzGhnZd9T8HJI2sJ86vEVB-Y_6XqfYX3CkdriJnePd8Yrnav-bw/s1600/linked-in-profile-pic-1743640118751.jfif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7674671342760410218.post-4434643657736488261</id><published>2025-01-11T18:56:00.026-06:00</published><updated>2025-02-03T13:38:42.491-06:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="linq to xml"/><title type='text'>How to Control Namespace Prefixes with LINQ to Xml</title><content type='html'>LINQ to Xml is a great improvement over the &lt;a href=&quot;https://learn.microsoft.com/en-us/dotnet/api/system.xml?view=net-9.0&quot; target=&quot;_blank&quot;&gt;XmlDocument DOM approach&lt;/a&gt; that uses types that are part of the &lt;code class=&quot;language-csharp&quot;&gt;System.Xml&lt;/code&gt; namespace. LINQ to Xml uses types that are part of the &lt;code class=&quot;language-csharp&quot;&gt;System.Xml.Linq&lt;/code&gt; namespace. In my experience, it shines for a large majority of the use cases for working with XML by offering a simpler method of accessing:
&lt;ul&gt;
  &lt;li&gt;Elements (XElement)&lt;/li&gt;
  &lt;li&gt;Attributes (XAttribute)&lt;/li&gt;
  &lt;li&gt;Nodes (XNode)&lt;/li&gt;
  &lt;li&gt;Comments (XComment)&lt;/li&gt;
  &lt;li&gt;Text (XText)&lt;/li&gt;
  &lt;li&gt;declarations (XDeclaration)&lt;/li&gt;
  &lt;li&gt;Namespaces (XNamespace)&lt;/li&gt;
  &lt;li&gt;Processing Instructions (XProcessingInstruction)&lt;/li&gt;
&lt;/ul&gt;

However, this post isn&#39;t intended to be an intro to LINQ to Xml. You can read more
about it &lt;a href=&quot;https://learn.microsoft.com/en-us/dotnet/api/system.xml.linq?view=net-9.0&quot; target=&quot;_blank&quot;&gt;here&lt;/a&gt;. The remaining use cases that need more complex and advanced XML processing are better handled by utilizing the XmlDocument DOM. This is because it has been around longer (since .NET Framework 1.1) whereas LINQ to Xml was added in .NET Framework 3.5. As a result the XmlDocument DOM is richer in features. I&#39;d liken it to working with C++ instead of C# - you can do a lot more with it and it&#39;s been around a lot longer, but it is more cumbersome to use than C#. Now getting back to the matter at hand...

When working with namespace prefixes using LINQ to Xml, it will handle the serialization of the prefixes for you. This is handled both by the &lt;code class=&quot;language-csharp&quot;&gt;XmlWriter&lt;/code&gt; as well as calling &lt;code class=&quot;language-csharp&quot;&gt;XDocument.ToString()&lt;/code&gt; or &lt;code class=&quot;language-csharp&quot;&gt;XElement.ToString()&lt;/code&gt;. This is helpful in most cases as it abstracts all of the details and just does it for you. It&#39;s not helpful when you need to control the prefixes that are serialized. Some examples of when you might need to control prefix serialization are:
&lt;ul&gt;&lt;li&gt;comparing documents for semantic equivalence&lt;/li&gt;
  &lt;li&gt;normalizing an xml document&lt;/li&gt;
  &lt;li&gt;or canonicalizing an xml document&lt;/li&gt;&lt;/ul&gt;
&lt;p&gt;Even LINQ to Xml&#39;s &lt;code class=&quot;language-csharp&quot;&gt;XNode.DeepEquals()&lt;/code&gt; method doesn&#39;t consider elements or attributes with different prefixes across XElement or XDocument instances to be equivalent. How disappointing.&amp;nbsp;&lt;/p&gt;
&lt;div&gt;Here is an example of how LINQ to Xml takes care of prefix serialization for you:&lt;/div&gt;
&lt;pre&gt;&lt;code class=&quot;language-csharp&quot;&gt;const string xml =  @&quot;
&amp;lt;x:root xmlns:x=&#39;http://ns1&#39; xmlns:y=&#39;http://ns2&#39;&amp;gt;
    &amp;lt;child a=&#39;1&#39; x:b=&#39;2&#39; y:c=&#39;3&#39;/&amp;gt;
&amp;lt;/x:root&amp;gt;&quot;;

XElement original = XElement.Parse(xml);

// Output the XML
Console.WriteLine(original.ToString());&lt;/code&gt;&lt;/pre&gt;

The output is:
&lt;pre&gt;&lt;code class=&quot;language-xml&quot;&gt;&amp;lt;x:root xmlns:x=&quot;http://ns1&quot; xmlns:y=&quot;http://ns2&quot;&amp;gt;
    &amp;lt;child a=&quot;1&quot; x:b=&quot;2&quot; y:c=&quot;3&quot; /&amp;gt;
&amp;lt;/x:root&amp;gt;&lt;/code&gt;&lt;/pre&gt;

Now create an XElement based on the original. This illustrates that the namespace prefixes specified in the original XElement are not maintained in the copy:
&lt;pre&gt;&lt;code class=&quot;language-csharp&quot;&gt;XElement copy =
  new XElement(original.Name,
    original.Elements()
      .Select(e =&amp;gt; new XElement(e.Name, e.Attributes(), e.Elements(), e.Value)));

Console.WriteLine(&quot;\nNew XElement:&quot;);
Console.WriteLine(copy.ToString());&lt;/code&gt;&lt;/pre&gt;

The output is:
&lt;pre&gt;&lt;code class=&quot;language-xml&quot;&gt;New XElement:
&amp;lt;root xmlns=&quot;http://ns1&quot;&amp;gt;
  &amp;lt;child a=&quot;1&quot; p2:b=&quot;2&quot; p3:c=&quot;3&quot; xmlns:p3=&quot;http://ns2&quot; xmlns:p2=&quot;http://ns1&quot; xmlns=&quot;&quot; /&amp;gt;
&amp;lt;/root&amp;gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;What happened to my prefixes of &lt;em&gt;x&lt;/em&gt; and &lt;em&gt;y&lt;/em&gt;? Where did the prefixes &lt;em&gt;p2&lt;/em&gt; and &lt;em&gt;p3&lt;/em&gt; come from? Also, note how there are some additional namespace declarations that aren&#39;t in the original &lt;code class=&quot;language-csharp&quot;&gt;XElement&lt;/code&gt;. We didn&#39;t touch anything related to namespaces when we created the copy; we just selected the elements and attributes from the original. You can&#39;t even use &lt;code class=&quot;language-csharp&quot;&gt;XNode.DeepEquals()&lt;/code&gt; to compare them for equivalence since the attributes are now different as well as the element names.  I&#39;ll leave that as an exercise for the reader.&lt;/p&gt;

&lt;p&gt;Controlling the prefixes yourself, although not very intuitive, is actually really easy. You might consider trying to change the Name property on the &lt;code class=&quot;language-csharp&quot;&gt;xmlns&lt;/code&gt; namespace declaration attribute to get the prefix rewritten. However, unlike the &lt;code class=&quot;language-csharp&quot;&gt;XElement.Name&lt;/code&gt; property which is writable, the &lt;code class=&quot;language-csharp&quot;&gt;XAttribute.Name&lt;/code&gt; property is readonly.

&lt;/p&gt;&lt;p&gt;&lt;strong&gt;One caveat here:&lt;/strong&gt; IF you happen to have superfluous (duplicate) namespace prefixes pointing to the same namespace, you are out of luck. I&#39;ve written a lengthy description about this on Stack Overflow answering this question: &lt;a href=&quot;https://stackoverflow.com/a/79353317/251267.&quot; target=&quot;_blank&quot;&gt;c# linq xml how to use two prefixes for same namespace&lt;/a&gt;.&lt;/p&gt;
  
&lt;p&gt;Would you believe me if I told you that LINQ is actually going to &lt;em&gt;help&lt;/em&gt; you rewrite the prefixes? In fact, it doesn&#39;t just help you, it rewrites all of the prefixes for you! I bet you didn&#39;t see that coming!  This is because modifications to the xml made at runtime cause LINQ to Xml to keep its tree updated so that it is in a consistent state. Imagine if you did made a programmatic change that caused the xml tree to be out of whack per se and the LINQ to Xml runtime didn&#39;t make updates for you to keep things in sync. Well, welcome to debugging hell.&lt;/p&gt;
    
&lt;p&gt;So, all we have to do are a couple of really simple things and LINQ to Xml handles the rewriting for us. There are two approaches: you can either create a new element or modify the existing one. I&#39;ve done some performance profiling and found that for larger documents above 1MB it is more efficient to create new elements and attributes rather than modifying existing ones. Some of this has to do with all of the allocations that are made when LINQ to Xml invokes the event handlers on the &lt;code class=&quot;language-csharp&quot;&gt;XObject&lt;/code&gt; class: see &lt;a href=&quot;https://learn.microsoft.com/en-us/dotnet/api/system.xml.linq.xobject?view=net-9.0&quot; target=&quot;_blank&quot;&gt;XObject Class&lt;/a&gt;. These are fired, thus allocating memory, regardless of whether you have event handlers wired to them or not.  I&#39;ll show you both patterns so you can decide what works for you. The steps to rewrite vary depending on which approach you decide upon.&lt;/p&gt;

&lt;div&gt;Let&#39;s use the following xml as an example with the assumption that we want to rewrite these prefixes for both namespaces that are declared and we want to rewrite prefix &lt;em&gt;a&lt;/em&gt; to &lt;em&gt;aNew&lt;/em&gt; and prefix &lt;em&gt;b&lt;/em&gt; to &lt;em&gt;bNew&lt;/em&gt;:&lt;/div&gt;
&lt;pre&gt;&lt;code class=&quot;language-csharp&quot;&gt;XNamespace origANamespace = &quot;http://www.a.com&quot;;
XNamespace origBNamespace = &quot;http://www.b.com&quot;;
const string originalAPrefix = &quot;a&quot;;
const string originalBPrefix = &quot;b&quot;;

const string xml = @&quot;
&amp;lt;a:foo xmlns:a=&#39;http://www.a.com&#39; xmlns:b=&#39;http://www.b.com&#39;&amp;gt;
  &amp;lt;b:bar/&amp;gt;
  &amp;lt;b:bar/&amp;gt;
  &amp;lt;b:bar/&amp;gt;
  &amp;lt;a:bar b:att1=&#39;val&#39;/&amp;gt;
&amp;lt;/a:foo&amp;gt;
&quot;&quot;&quot;;&lt;/code&gt;&lt;/pre&gt;

    &lt;h3&gt;Creating a new XElement&lt;/h3&gt;

There are three steps.

&lt;div&gt;&lt;b&gt;Step 1: Create a new XNamespace and point it to the namespace whose prefix should be rewritten&lt;/b&gt;&lt;/div&gt;
&lt;pre&gt;&lt;code class=&quot;language-csharp&quot;&gt;// Define new namespaces
XNamespace newANamespace = origANamespace;
XNamespace newBNamespace = origBNamespace;&lt;/code&gt;&lt;/pre&gt;

&lt;div&gt;&lt;b&gt;Step 2: Create new namespace declaration attributes that use the XNamespaces you created in Step 1&lt;/b&gt;&lt;/div&gt;
&lt;pre&gt;&lt;code class=&quot;language-csharp&quot;&gt;XAttribute newANamespaceXmlnsAttr =
  new XAttribute(XNamespace.Xmlns + &quot;aNew&quot;, newANamespace);
XAttribute newBNamespaceXmlnsAttr =
  new XAttribute(XNamespace.Xmlns + &quot;bNew&quot;, newBNamespace);&lt;/code&gt;&lt;/pre&gt;

&lt;div&gt;&lt;b&gt;Step 3: Create a XElement that you will use this new namespace and contains all of the elements, attributes, and children of the original XElement&lt;/b&gt;&lt;/div&gt;
&lt;pre&gt;&lt;code class=&quot;language-csharp&quot;&gt;// Create a new XElement with the new namespace  
XElement newElement = 
  new XElement(newANamespace + originalElement.Name.LocalName,
    newANamespaceXmlnsAttr,
    newBNamespaceXmlnsAttr,
    originalElement
      .Elements()
      .Select(e =&amp;gt; 
        new XElement(
          e.Name,
          e.Attributes(),
          e.Elements(),
          e.Value)));&lt;/code&gt;&lt;/pre&gt;



&lt;h3&gt;Modifying an existing XElement&lt;/h3&gt;

There are four steps with the last step being optional depending if you want to remove the old namespace prefix declaration. THe first two steps are identical to the creating a new &lt;code class=&quot;language-csharp&quot;&gt;XElement&lt;/code&gt; approach.

&lt;div&gt;&lt;b&gt;Step 1: Create a new XNamespace that has the new prefix you want and point it to the namespace whose prefix should be rewritten&lt;/b&gt;&lt;/div&gt;
&lt;pre&gt;&lt;code class=&quot;language-csharp&quot;&gt;// Define new namespaces
XNamespace newANamespace = origANamespace;
XNamespace newBNamespace = origBNamespace;&lt;/code&gt;&lt;/pre&gt;

&lt;div&gt;&lt;b&gt;Step 2: Create new namespace declaration attributes that use the XNamespaces you created in Step 1&lt;/b&gt;&lt;/div&gt;
&lt;pre&gt;&lt;code class=&quot;language-csharp&quot;&gt;XAttribute newANamespaceXmlnsAttr =
  new XAttribute(XNamespace.Xmlns + &quot;aNew&quot;, newANamespace);
XAttribute newBNamespaceXmlnsAttr =
  new XAttribute(XNamespace.Xmlns + &quot;bNew&quot;, newBNamespace);&lt;/code&gt;&lt;/pre&gt;

&lt;div&gt;&lt;b&gt;Step 3: Modify the original XElement by adding the new namespace declaration attributes&lt;/b&gt;&lt;/div&gt;
&lt;pre&gt;&lt;code class=&quot;language-csharp&quot;&gt;originalElement.Add(
  newANamespaceXmlnsAttr,
  newBNamespaceXmlnsAttr);
&lt;/code&gt;&lt;/pre&gt;

&lt;div&gt;&lt;b&gt;Step 4 (optional): Remove the original namespace declaration that has now been rewritten&lt;/b&gt;&lt;/div&gt;
&lt;pre&gt;&lt;code class=&quot;language-csharp&quot;&gt;// now remove the original &#39;a&#39; and &#39;b&#39; namespace declarations
originalElement
  .Attribute(XNamespace.Xmlns + originalAPrefix)?
  .Remove();
originalElement
  .Attribute(XNamespace.Xmlns + originalBPrefix)?
  .Remove();
&lt;/code&gt;&lt;/pre&gt;

I hope you found this helpful. Drop a comment and let me know.&lt;p&gt;&lt;/p&gt;</content><link rel='replies' type='application/atom+xml' href='http://dave-black.blogspot.com/feeds/4434643657736488261/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://dave-black.blogspot.com/2025/01/how-to-control-namespace-prefixes-with.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7674671342760410218/posts/default/4434643657736488261'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7674671342760410218/posts/default/4434643657736488261'/><link rel='alternate' type='text/html' href='http://dave-black.blogspot.com/2025/01/how-to-control-namespace-prefixes-with.html' title='How to Control Namespace Prefixes with LINQ to Xml'/><author><name>Dave Black</name><uri>http://www.blogger.com/profile/11787334586939943513</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEghXqyOIYI80jcRqlgdIPg99-1bldyR6NKQgYGs8Uq_88qc_HNUrHXqM0R_9FvephlqkYzrrmMwMjSs7JV9QVSQAZMlO5hinHcLQrYmcSTRbCS-g4JIfIJaOYteBSxEzGhnZd9T8HJI2sJ86vEVB-Y_6XqfYX3CkdriJnePd8Yrnav-bw/s1600/linked-in-profile-pic-1743640118751.jfif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7674671342760410218.post-4078561540804722022</id><published>2024-12-24T18:21:00.004-06:00</published><updated>2025-02-03T13:39:32.484-06:00</updated><category scheme="http://www.blogger.com/atom/ns#" term=".net"/><category scheme="http://www.blogger.com/atom/ns#" term="debug"/><category scheme="http://www.blogger.com/atom/ns#" term="debugging"/><category scheme="http://www.blogger.com/atom/ns#" term="memory management"/><category scheme="http://www.blogger.com/atom/ns#" term="sos"/><category scheme="http://www.blogger.com/atom/ns#" term="tools"/><category scheme="http://www.blogger.com/atom/ns#" term="windbg"/><title type='text'>Memory Leaks - Part 2: Debugging Tools to Diagnose a Memory Leak</title><content type='html'>If you are reading this you may be in the unfortunate position of looking for an elusive and possibly intermittent problem in your production application. Debugging and diagnosing a memory leak or an &lt;span style=&quot;font-family: courier;&quot;&gt;OutOfMemoryException &lt;/span&gt;can be a daunting, intimidating and challenging task.  Fortunately, there are a number of tools to help; some of these are &quot;paid license&quot; apps, but there are even more tools that are free. I&#39;ll discuss some .NET Debugging Tools available. I&#39;ve used all of the following tools with the exception of SciTech .NET Memory Profiler. Each has its advantages and disadvantages. Personally, I prefer the free tools for several reasons:&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;ol style=&quot;text-align: left;&quot;&gt;&lt;li&gt;Getting approval for licensing and purchase of a 3rd-party tool is an uphill task and you rarely have time to wait for the approval process when it is a production issue.&lt;/li&gt;&lt;li&gt;I find the feature set of a combination of the free tools gives you the largest &quot;surface area&quot; of features to help. Some are better at strict data collection, others have graphical views, some are static for post-mortem debugging, and others can do real-time analysis.&lt;/li&gt;&lt;li&gt;Even though these are free, they are very robust and provide just as much data as the paid license tools. A good example of this is WinDbg which was developed in 1993 by Microsoft for in-house debugging of the Windows Kernel.&lt;/li&gt;&lt;/ol&gt;&lt;div&gt;
&lt;h3 style=&quot;text-align: left;&quot;&gt;&lt;span style=&quot;font-size: large;&quot;&gt;Free Tools&lt;/span&gt;&lt;/h3&gt;&lt;h4 style=&quot;text-align: left;&quot;&gt;Advantages&lt;/h4&gt;&lt;div&gt;&lt;ul style=&quot;text-align: left;&quot;&gt;&lt;li&gt;Duh! It&#39;s free&lt;/li&gt;&lt;li&gt;There are lots of tools to choose from&lt;/li&gt;&lt;li&gt;All of the ones I&#39;ve seen are from reputable and well-known companies.&lt;/li&gt;&lt;li&gt;You can often find blog posts (ahem...), articles, reddit threads, etc. that can provide some direction for getting started.&lt;/li&gt;&lt;/ul&gt;&lt;h4 style=&quot;text-align: left;&quot;&gt;Disadvantages&lt;/h4&gt;&lt;/div&gt;&lt;div&gt;&lt;ul style=&quot;text-align: left;&quot;&gt;&lt;li&gt;Formal documentation can be lacking. Finding a blog post or article is great but comprehensive detail is often missing or at best glossed over. This can make getting started a bit more of a challenge if the tool is new to you.&lt;/li&gt;&lt;li&gt;Your company may have restrictions on using free tools for fear of malware, liability, or other reasons.&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;&lt;ul style=&quot;text-align: left;&quot;&gt;&lt;li&gt;&lt;u&gt;Windows Task Manager&lt;/u&gt;: taskmgr.exe. Make sure to make the following columns visible:&lt;/li&gt;
&lt;ul&gt;
&lt;li&gt;Memory - Working Set&lt;/li&gt;
&lt;li&gt;Memory - Private Working Set&lt;/li&gt;
&lt;li&gt;Memory - Commit Size&lt;/li&gt;
&lt;li&gt;Threads&lt;/li&gt;
&lt;li&gt;Handles&lt;/li&gt;
&lt;li&gt;USER Objects (if WinForm or Native app)&lt;/li&gt;
&lt;li&gt;GDI Objects (if WinForm or Native app)&lt;/li&gt;
&lt;/ul&gt;
&lt;li&gt;&lt;u&gt;Windows Performance Monitor&lt;/u&gt;: perfmon.exe&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://technet.microsoft.com/en-us/sysinternals/bb896653.aspx&quot; target=&quot;_blank&quot;&gt;Process Explorer&lt;/a&gt; (SysInternals)&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://technet.microsoft.com/en-us/sysinternals/dd535533.aspx&quot; target=&quot;_blank&quot;&gt;VM Map&lt;/a&gt; (SysInternals)&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://www.microsoft.com/whdc/devtools/debugging/%20&quot; target=&quot;_blank&quot;&gt;Debugging Tools for Windows (WinDbg, SOS, Kernel Debugger, etc.)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://www.microsoft.com/download/en/details.aspx?id=26798&quot; target=&quot;_blank&quot;&gt;Microsoft Debug Diagnostic Tool (DebugDiag)&lt;/a&gt; &lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://www.microsoft.com/download/en/details.aspx?id=1073&quot; target=&quot;_blank&quot;&gt;Psscor2 - WinDbg debugger extension for ASP.NET 2.0, 3.5&lt;/a&gt;&lt;a href=&quot;http://www.microsoft.com/download/en/details.aspx?id=1073&quot; target=&quot;_blank&quot;&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://www.microsoft.com/download/en/details.aspx?id=21255&quot; target=&quot;_blank&quot;&gt;Psscor4 - WinDbg debugger extension for ASP.NET 4.x&lt;/a&gt;&lt;a href=&quot;http://www.microsoft.com/download/en/details.aspx?id=21255&quot; target=&quot;_blank&quot;&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://www.stevestechspot.com/MajorSOSEXUpdate.aspx&quot; target=&quot;_blank&quot;&gt;SOSEX from Steve Johnson (.NET 2.0, 3.5)&lt;/a&gt;&lt;a href=&quot;http://www.stevestechspot.com/MajorSOSEXUpdate.aspx&quot; target=&quot;_blank&quot;&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://www.stevestechspot.com/SOSEXV4Update.aspx&quot; target=&quot;_blank&quot;&gt;SOSEX 4 from Steve Johnson (.NET 4.x)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://www.microsoft.com/download/en/details.aspx?id=26798&quot; target=&quot;_blank&quot;&gt;IISInfo - WinDbg debugger extension (included with DebugDiag)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://www.microsoft.com/download/en/details.aspx?id=20028&quot; target=&quot;_blank&quot;&gt;Microsoft Application Verifier&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://www.microsoft.com/download/en/details.aspx?id=13382&quot; target=&quot;_blank&quot;&gt;CLR Profiler 2.0&lt;/a&gt; (good for finding heap fragmentation)&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://www.microsoft.com/download/en/details.aspx?id=16273&quot; target=&quot;_blank&quot;&gt;CLR Profiler 4.0&lt;/a&gt; (good for finding heap fragmentation)&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://msdn.microsoft.com/en-us/performance/default.aspx&quot; target=&quot;_blank&quot;&gt;Windows Performance Toolkit (xperf)&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 style=&quot;text-align: left;&quot;&gt;&lt;span style=&quot;font-size: large;&quot;&gt;Licensed Tools&lt;/span&gt;&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;http://www.red-gate.com/products/ants_memory_profiler&quot; target=&quot;_blank&quot;&gt;RedGate Ants Memory Profiler&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://www.componentsource.com/&quot; target=&quot;_blank&quot;&gt;Micro Focus DevPartner Studio&lt;/a&gt; (formerly Compuware)&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://memprofiler.com/&quot; target=&quot;_blank&quot;&gt;SciTech .NET Memory Profiler&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://smartbear.com/products/development-tools/performance-profiling/&quot; target=&quot;_blank&quot;&gt;AQ Time Pro&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
Hope this helps! &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;&lt;/div&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dave-black.blogspot.com/feeds/4078561540804722022/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://dave-black.blogspot.com/2011/12/debugging-tools-to-diagnose-memory-leak.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7674671342760410218/posts/default/4078561540804722022'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7674671342760410218/posts/default/4078561540804722022'/><link rel='alternate' type='text/html' href='http://dave-black.blogspot.com/2011/12/debugging-tools-to-diagnose-memory-leak.html' title='Memory Leaks - Part 2: Debugging Tools to Diagnose a Memory Leak'/><author><name>Dave Black</name><uri>http://www.blogger.com/profile/11787334586939943513</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEghXqyOIYI80jcRqlgdIPg99-1bldyR6NKQgYGs8Uq_88qc_HNUrHXqM0R_9FvephlqkYzrrmMwMjSs7JV9QVSQAZMlO5hinHcLQrYmcSTRbCS-g4JIfIJaOYteBSxEzGhnZd9T8HJI2sJ86vEVB-Y_6XqfYX3CkdriJnePd8Yrnav-bw/s1600/linked-in-profile-pic-1743640118751.jfif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7674671342760410218.post-8295795387134322344</id><published>2019-05-14T15:49:00.002-05:00</published><updated>2025-02-03T13:39:49.674-06:00</updated><category scheme="http://www.blogger.com/atom/ns#" term=".net 5"/><category scheme="http://www.blogger.com/atom/ns#" term=".net core"/><category scheme="http://www.blogger.com/atom/ns#" term=".net framework"/><title type='text'>Unifying .NET - One framework to rule them all?</title><content type='html'>&lt;div class=&quot;mentions-texteditor__content&quot; style=&quot;background: 0px 0px rgb(255, 255, 255); border: 0px; box-sizing: inherit; color: rgba(0, 0, 0, 0.9); font-family: -apple-system, system-ui, BlinkMacSystemFont, &amp;quot;Segoe UI&amp;quot;, Roboto, &amp;quot;Helvetica Neue&amp;quot;, &amp;quot;Fira Sans&amp;quot;, Ubuntu, Oxygen, &amp;quot;Oxygen Sans&amp;quot;, Cantarell, &amp;quot;Droid Sans&amp;quot;, &amp;quot;Apple Color Emoji&amp;quot;, &amp;quot;Segoe UI Emoji&amp;quot;, &amp;quot;Segoe UI Emoji&amp;quot;, &amp;quot;Segoe UI Symbol&amp;quot;, &amp;quot;Lucida Grande&amp;quot;, Helvetica, Arial, sans-serif; font-size: 18px; line-height: 1.5; padding: 0px; vertical-align: baseline;&quot;&gt;.NET 5 is on the way and scheduled to be delivered in November 2020. It is meant to unify .NET Framework, .NET Core, Mono (and possibly .NET Standard) - i.e. the entire&amp;nbsp;.NET Platform.&lt;/div&gt;
&lt;div class=&quot;mentions-texteditor__content&quot; style=&quot;background: 0px 0px rgb(255, 255, 255); border: 0px; box-sizing: inherit; color: rgba(0, 0, 0, 0.9); font-family: -apple-system, system-ui, BlinkMacSystemFont, &amp;quot;Segoe UI&amp;quot;, Roboto, &amp;quot;Helvetica Neue&amp;quot;, &amp;quot;Fira Sans&amp;quot;, Ubuntu, Oxygen, &amp;quot;Oxygen Sans&amp;quot;, Cantarell, &amp;quot;Droid Sans&amp;quot;, &amp;quot;Apple Color Emoji&amp;quot;, &amp;quot;Segoe UI Emoji&amp;quot;, &amp;quot;Segoe UI Emoji&amp;quot;, &amp;quot;Segoe UI Symbol&amp;quot;, &amp;quot;Lucida Grande&amp;quot;, Helvetica, Arial, sans-serif; font-size: 18px; line-height: 1.5; padding: 0px; vertical-align: baseline;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class=&quot;mentions-texteditor__content&quot; style=&quot;background: 0px 0px rgb(255, 255, 255); border: 0px; box-sizing: inherit; color: rgba(0, 0, 0, 0.9); font-family: -apple-system, system-ui, BlinkMacSystemFont, &amp;quot;Segoe UI&amp;quot;, Roboto, &amp;quot;Helvetica Neue&amp;quot;, &amp;quot;Fira Sans&amp;quot;, Ubuntu, Oxygen, &amp;quot;Oxygen Sans&amp;quot;, Cantarell, &amp;quot;Droid Sans&amp;quot;, &amp;quot;Apple Color Emoji&amp;quot;, &amp;quot;Segoe UI Emoji&amp;quot;, &amp;quot;Segoe UI Emoji&amp;quot;, &amp;quot;Segoe UI Symbol&amp;quot;, &amp;quot;Lucida Grande&amp;quot;, Helvetica, Arial, sans-serif; font-size: 18px; line-height: 1.5; padding: 0px; vertical-align: baseline;&quot;&gt;
After 17 years of working in .NET (since it was first released in 2002), I&#39;m excited to see a unified solution to the splintered framework that .NET has become as of late.&amp;nbsp; IMO, .NET Framework, .NET Core, .NET Standard, and Mono have grown into a big bad monster that is growing faster than its parts can manage. While we know (and expect) technology to evolve and grow over time, we hope that it doesn&#39;t fragment and splinter so much that its parts become dissimilar.&amp;nbsp; I&#39;ve seen it grow from a set of APIs that were questionable to something that is almost overwhelming - and certainly difficult to keep up with.&amp;nbsp; I&#39;m pleased to see that Microsoft has acknowledged the splintering and has been working on a solution since at least December 2018.&amp;nbsp; I&#39;m looking forward to seeing how much simpler things will become.&lt;/div&gt;
&lt;div class=&quot;mentions-texteditor__content&quot; style=&quot;background: 0px 0px rgb(255, 255, 255); border: 0px; box-sizing: inherit; color: rgba(0, 0, 0, 0.9); font-family: -apple-system, system-ui, BlinkMacSystemFont, &amp;quot;Segoe UI&amp;quot;, Roboto, &amp;quot;Helvetica Neue&amp;quot;, &amp;quot;Fira Sans&amp;quot;, Ubuntu, Oxygen, &amp;quot;Oxygen Sans&amp;quot;, Cantarell, &amp;quot;Droid Sans&amp;quot;, &amp;quot;Apple Color Emoji&amp;quot;, &amp;quot;Segoe UI Emoji&amp;quot;, &amp;quot;Segoe UI Emoji&amp;quot;, &amp;quot;Segoe UI Symbol&amp;quot;, &amp;quot;Lucida Grande&amp;quot;, Helvetica, Arial, sans-serif; font-size: 18px; line-height: 1.5; padding: 0px; vertical-align: baseline;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class=&quot;mentions-texteditor__content&quot; style=&quot;background: 0px 0px rgb(255, 255, 255); border: 0px; box-sizing: inherit; color: rgba(0, 0, 0, 0.9); font-family: -apple-system, system-ui, BlinkMacSystemFont, &amp;quot;Segoe UI&amp;quot;, Roboto, &amp;quot;Helvetica Neue&amp;quot;, &amp;quot;Fira Sans&amp;quot;, Ubuntu, Oxygen, &amp;quot;Oxygen Sans&amp;quot;, Cantarell, &amp;quot;Droid Sans&amp;quot;, &amp;quot;Apple Color Emoji&amp;quot;, &amp;quot;Segoe UI Emoji&amp;quot;, &amp;quot;Segoe UI Emoji&amp;quot;, &amp;quot;Segoe UI Symbol&amp;quot;, &amp;quot;Lucida Grande&amp;quot;, Helvetica, Arial, sans-serif; font-size: 18px; line-height: 1.5; padding: 0px; vertical-align: baseline;&quot;&gt;
&lt;a href=&quot;https://devblogs.microsoft.com/dotnet/introducing-net-5/&quot;&gt;https://devblogs.microsoft.com/dotnet/introducing-net-5/&lt;/a&gt;&lt;/div&gt;
&lt;div class=&quot;mentions-texteditor__content&quot; style=&quot;background: 0px 0px rgb(255, 255, 255); border: 0px; box-sizing: inherit; color: rgba(0, 0, 0, 0.9); font-family: -apple-system, system-ui, BlinkMacSystemFont, &amp;quot;Segoe UI&amp;quot;, Roboto, &amp;quot;Helvetica Neue&amp;quot;, &amp;quot;Fira Sans&amp;quot;, Ubuntu, Oxygen, &amp;quot;Oxygen Sans&amp;quot;, Cantarell, &amp;quot;Droid Sans&amp;quot;, &amp;quot;Apple Color Emoji&amp;quot;, &amp;quot;Segoe UI Emoji&amp;quot;, &amp;quot;Segoe UI Emoji&amp;quot;, &amp;quot;Segoe UI Symbol&amp;quot;, &amp;quot;Lucida Grande&amp;quot;, Helvetica, Arial, sans-serif; font-size: 18px; line-height: 1.5; padding: 0px; vertical-align: baseline;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class=&quot;mentions-texteditor__content&quot; style=&quot;background: 0px 0px rgb(255, 255, 255); border: 0px; box-sizing: inherit; color: rgba(0, 0, 0, 0.9); font-family: -apple-system, system-ui, BlinkMacSystemFont, &amp;quot;Segoe UI&amp;quot;, Roboto, &amp;quot;Helvetica Neue&amp;quot;, &amp;quot;Fira Sans&amp;quot;, Ubuntu, Oxygen, &amp;quot;Oxygen Sans&amp;quot;, Cantarell, &amp;quot;Droid Sans&amp;quot;, &amp;quot;Apple Color Emoji&amp;quot;, &amp;quot;Segoe UI Emoji&amp;quot;, &amp;quot;Segoe UI Emoji&amp;quot;, &amp;quot;Segoe UI Symbol&amp;quot;, &amp;quot;Lucida Grande&amp;quot;, Helvetica, Arial, sans-serif; font-size: 18px; line-height: 1.5; padding: 0px; vertical-align: baseline;&quot;&gt;
Now if they could just FINALLY fix &quot;Edit and Continue&quot;...........&lt;/div&gt;
&lt;div class=&quot;mentions-texteditor__content&quot; style=&quot;background: 0px 0px rgb(255, 255, 255); border: 0px; box-sizing: inherit; color: rgba(0, 0, 0, 0.9); font-family: -apple-system, system-ui, BlinkMacSystemFont, &amp;quot;Segoe UI&amp;quot;, Roboto, &amp;quot;Helvetica Neue&amp;quot;, &amp;quot;Fira Sans&amp;quot;, Ubuntu, Oxygen, &amp;quot;Oxygen Sans&amp;quot;, Cantarell, &amp;quot;Droid Sans&amp;quot;, &amp;quot;Apple Color Emoji&amp;quot;, &amp;quot;Segoe UI Emoji&amp;quot;, &amp;quot;Segoe UI Emoji&amp;quot;, &amp;quot;Segoe UI Symbol&amp;quot;, &amp;quot;Lucida Grande&amp;quot;, Helvetica, Arial, sans-serif; font-size: 18px; line-height: 1.5; padding: 0px; vertical-align: baseline;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://devblogs.microsoft.com/dotnet/wp-content/uploads/sites/10/2019/05/dotnet5_platform.png&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;426&quot; data-original-width=&quot;800&quot; height=&quot;339&quot; src=&quot;https://devblogs.microsoft.com/dotnet/wp-content/uploads/sites/10/2019/05/dotnet5_platform.png&quot; width=&quot;640&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
(image is copyright of Microsoft)&lt;/div&gt;
&lt;div class=&quot;mentions-texteditor__content&quot; style=&quot;background: 0px 0px rgb(255, 255, 255); border: 0px; box-sizing: inherit; color: rgba(0, 0, 0, 0.9); font-family: -apple-system, system-ui, BlinkMacSystemFont, &amp;quot;Segoe UI&amp;quot;, Roboto, &amp;quot;Helvetica Neue&amp;quot;, &amp;quot;Fira Sans&amp;quot;, Ubuntu, Oxygen, &amp;quot;Oxygen Sans&amp;quot;, Cantarell, &amp;quot;Droid Sans&amp;quot;, &amp;quot;Apple Color Emoji&amp;quot;, &amp;quot;Segoe UI Emoji&amp;quot;, &amp;quot;Segoe UI Emoji&amp;quot;, &amp;quot;Segoe UI Symbol&amp;quot;, &amp;quot;Lucida Grande&amp;quot;, Helvetica, Arial, sans-serif; font-size: 18px; line-height: 1.5; padding: 0px; vertical-align: baseline;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
</content><link rel='replies' type='application/atom+xml' href='http://dave-black.blogspot.com/feeds/8295795387134322344/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://dave-black.blogspot.com/2019/05/unifying-net.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7674671342760410218/posts/default/8295795387134322344'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7674671342760410218/posts/default/8295795387134322344'/><link rel='alternate' type='text/html' href='http://dave-black.blogspot.com/2019/05/unifying-net.html' title='Unifying .NET - One framework to rule them all?'/><author><name>Dave Black</name><uri>http://www.blogger.com/profile/11787334586939943513</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEghXqyOIYI80jcRqlgdIPg99-1bldyR6NKQgYGs8Uq_88qc_HNUrHXqM0R_9FvephlqkYzrrmMwMjSs7JV9QVSQAZMlO5hinHcLQrYmcSTRbCS-g4JIfIJaOYteBSxEzGhnZd9T8HJI2sJ86vEVB-Y_6XqfYX3CkdriJnePd8Yrnav-bw/s1600/linked-in-profile-pic-1743640118751.jfif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7674671342760410218.post-7846136791065305872</id><published>2019-04-19T13:09:00.000-05:00</published><updated>2019-04-19T13:09:05.407-05:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="visual studio"/><title type='text'>Missing Start Page from Visual Studio 2019</title><content type='html'>Oh Microsoft, why hast thou forsaken the beloved &#39;Start Page&#39; and replaced it with a modal window?&lt;br /&gt;
&lt;br /&gt;
&lt;table align=&quot;center&quot; cellpadding=&quot;0&quot; cellspacing=&quot;0&quot; class=&quot;tr-caption-container&quot; style=&quot;margin-left: auto; margin-right: auto; text-align: center;&quot;&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td style=&quot;text-align: center;&quot;&gt;&lt;img height=&quot;437&quot; src=&quot;https://devblogs.microsoft.com/wp-content/uploads/sites/4/2019/06/startwindowP1.png&quot; style=&quot;margin-left: auto; margin-right: auto;&quot; width=&quot;640&quot; /&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;tr-caption&quot; style=&quot;text-align: center;&quot;&gt;The new &#39;Start Window&#39; which replaces the &#39;Start Page&#39;&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;br /&gt;
You can see the design reasoning behind the new VS 2019 Start Window as posted at&amp;nbsp;&lt;a href=&quot;https://devblogs.microsoft.com/visualstudio/get-to-code-how-we-designed-the-new-visual-studio-start-window/&quot; target=&quot;_blank&quot;&gt;&#39;Get to code: How we designed the new Visual Studio start window&#39;&lt;/a&gt;&amp;nbsp;and&amp;nbsp;&lt;a href=&quot;https://devblogs.microsoft.com/cppblog/new-start-window-and-new-project-dialog-experience-in-visual-studio-2019/&quot; target=&quot;_blank&quot;&gt;&#39;New Start Window and New Project Dialog Experience in Visual Studio 2019&#39;&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
I sincerely appreciate any amount of thought, consideration, or testing that a company decides to invest in their products - especially a flagship produce like Visual Studio.&amp;nbsp; Based on the design reasoning Microsoft certainly had good intentions and did put a good amount of thought and testing into the effort.&amp;nbsp; However, I think they missed the mark.&amp;nbsp; Perform any Google search on &quot;missing start page visual studio 2019&quot; or look on the&amp;nbsp;&lt;a href=&quot;https://developercommunity.visualstudio.com/&quot; target=&quot;_blank&quot;&gt;Developer Community Feedback Site&lt;/a&gt;&amp;nbsp;and you&#39;ll see devs crying out for the beloved Start Page.&lt;br /&gt;
&lt;br /&gt;
Some things are better left untouched and left alone and the Start Page is one of them. Some might argue the new &#39;Start Window&#39; is a better experience but why make it a modal window?&amp;nbsp; Really?&amp;nbsp; In Visual Studio 2019 Preview 1, at least the option to restore the &#39;Start Page&#39; was available as an option in the Startup settings:&lt;br /&gt;
&lt;br /&gt;
&lt;a data-featherlight=&quot;image&quot; href=&quot;https://devblogs.microsoft.com/cppblog/wp-content/uploads/sites/9/2019/01/turn-off-start-window1.png&quot; style=&quot;background-color: white; box-sizing: border-box; color: #005da6; font-family: &amp;quot;Segoe UI&amp;quot;, &amp;quot;Segoe UI Web Regular&amp;quot;, &amp;quot;Segoe UI Regular WestEuropean&amp;quot;, &amp;quot;Segoe UI&amp;quot;, Tahoma, Arial, Roboto, &amp;quot;Helvetica Neue&amp;quot;, sans-serif, &amp;quot;Apple Color Emoji&amp;quot;, &amp;quot;Segoe UI Emoji&amp;quot;, &amp;quot;Segoe UI Symbol&amp;quot;; font-size: 17px;&quot;&gt;&lt;img alt=&quot;&quot; class=&quot;aligncenter size-full wp-image-22065&quot; height=&quot;603&quot; src=&quot;https://devblogs.microsoft.com/cppblog/wp-content/uploads/sites/9/2019/01/turn-off-start-window1.png&quot; style=&quot;border-style: none; box-sizing: border-box; cursor: zoom-in; display: block; height: auto; margin: 0px auto; max-width: 100%; vertical-align: middle;&quot; width=&quot;740&quot; /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
However, somewhere along the way the &#39;Start Page&#39; item has disappeared from the drop-down...headsmack!&amp;nbsp; Here&#39;s what the options are in version 16.0.2:&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi9OzuyvvICU1sDS6Tlx7Vj0N_zv_qJ86s1rTu_MS054e8vzQnc2dAfcuhJO8VKPd8XE1K03RABmwFO9efY8r2i-5Oer-z6y33ds3IWxSp9WKWijnAU0s9FWl1CpaTcP4rBDB8c9wKHs8I/s1600/startup.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;710&quot; data-original-width=&quot;1053&quot; height=&quot;428&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi9OzuyvvICU1sDS6Tlx7Vj0N_zv_qJ86s1rTu_MS054e8vzQnc2dAfcuhJO8VKPd8XE1K03RABmwFO9efY8r2i-5Oer-z6y33ds3IWxSp9WKWijnAU0s9FWl1CpaTcP4rBDB8c9wKHs8I/s640/startup.png&quot; width=&quot;640&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;br /&gt;
Ok, now I&#39;m getting frustrated.&amp;nbsp; I get it. You&#39;re trying to funnel me into this new window that you think is better.&amp;nbsp; Well, my response is&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEisGhW5Mfy2eisVD67Tdo7Fm1277CkkiHnC4zPNbgPJKm3ipepaaVYBj69OoJNGUSIYtSX8qHV8F-bPi4a4uhAtEj7MUzCQPM42bTgMT45PJEu0MmKUpC4cvd0qNsopkujOyS6aH2Hm5gY/s1600/nosir.gif&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;375&quot; data-original-width=&quot;500&quot; height=&quot;240&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEisGhW5Mfy2eisVD67Tdo7Fm1277CkkiHnC4zPNbgPJKm3ipepaaVYBj69OoJNGUSIYtSX8qHV8F-bPi4a4uhAtEj7MUzCQPM42bTgMT45PJEu0MmKUpC4cvd0qNsopkujOyS6aH2Hm5gY/s320/nosir.gif&quot; width=&quot;320&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
Fortunately, Microsoft hasn&#39;t &lt;i&gt;completely&lt;/i&gt;&amp;nbsp;done away with the &#39;Start Page&#39;...yet.&amp;nbsp; You can still add it by customizing the toolbar to add the Start Page button:&lt;br /&gt;
&lt;br /&gt;
1. Right-click the toolbar and select &#39;Customize&#39;:&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEikRmoMjbBUuDZ96Ibb0izKCKOJQ0iV7-bJ4oprvnCgdHed1ePwd7s5m_-_5HqB1RIHJEjwPTgcvDC-CHfxf7vneo0LWEZHupRV2njinzcIKxaCNDERha5moFxROv3HsZemjZvfO3AKzqE/s1600/customize.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;874&quot; data-original-width=&quot;428&quot; height=&quot;400&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEikRmoMjbBUuDZ96Ibb0izKCKOJQ0iV7-bJ4oprvnCgdHed1ePwd7s5m_-_5HqB1RIHJEjwPTgcvDC-CHfxf7vneo0LWEZHupRV2njinzcIKxaCNDERha5moFxROv3HsZemjZvfO3AKzqE/s400/customize.png&quot; width=&quot;195&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
2. Select the &#39;Commands&#39; tab:&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjVNWymHrdANzlb30FrYHZsttLaX4ynvNZVPxBS4YzSwgxGcf-bf0C6MBk5Ah82uyyIvj08mIdZ-2YvFXmGH3oSg6M3a_7Ny6OqDASUIsG5kkmr1Jn662oclVXUwRyanREF-COXHPGdV4Y/s1600/commands.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;815&quot; data-original-width=&quot;783&quot; height=&quot;400&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjVNWymHrdANzlb30FrYHZsttLaX4ynvNZVPxBS4YzSwgxGcf-bf0C6MBk5Ah82uyyIvj08mIdZ-2YvFXmGH3oSg6M3a_7Ny6OqDASUIsG5kkmr1Jn662oclVXUwRyanREF-COXHPGdV4Y/s400/commands.png&quot; width=&quot;383&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
3. Select &#39;Toolbar&#39; and change the dropdown to whatever menu you&#39;d like, then click the &#39;Add Command&#39; button:&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEidTi3HFA8VhAVaHi6PPPaASNA4FJNSBH5np_HLXt6O8gF6sDcrpRWEr751KOJweBZxsJu4mDbTmNBGqC41PaxEfdc0QVgCgrPsfTQ7xI2x22qqglPUlLGuqjnpOfk0OxoPu_Iu7EKJ3kw/s1600/toolbar.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;815&quot; data-original-width=&quot;783&quot; height=&quot;400&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEidTi3HFA8VhAVaHi6PPPaASNA4FJNSBH5np_HLXt6O8gF6sDcrpRWEr751KOJweBZxsJu4mDbTmNBGqC41PaxEfdc0QVgCgrPsfTQ7xI2x22qqglPUlLGuqjnpOfk0OxoPu_Iu7EKJ3kw/s400/toolbar.png&quot; width=&quot;383&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
4. Choose &#39;File&#39; from the Categories list box, then select &#39;Start Page&#39; from the Commands list box:&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEikq5j8bcLR2zTzSpfIeEXzrJX6x0l-Rp9P2SU4Icoz2Cqt2GSVO_RYYkKZIjObS_jE77huUcEnvOM9pk1ZYD_Ed5AnU29UF8Y3kHXVrlZyNT7xmcqFK_YhUoas2cqShttzpx0IYDHcc_o/s1600/addcommand.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;545&quot; data-original-width=&quot;858&quot; height=&quot;253&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEikq5j8bcLR2zTzSpfIeEXzrJX6x0l-Rp9P2SU4Icoz2Cqt2GSVO_RYYkKZIjObS_jE77huUcEnvOM9pk1ZYD_Ed5AnU29UF8Y3kHXVrlZyNT7xmcqFK_YhUoas2cqShttzpx0IYDHcc_o/s400/addcommand.png&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
So, there you go!&amp;nbsp; At least it&#39;s still there for now.&amp;nbsp; I&#39;d bet any amount of money that they change the experience back so that either the &#39;Start Page&#39; option is available from the Environment/Startup setting. To be fair, Microsoft has improved significantly at listening to community feedback.</content><link rel='replies' type='application/atom+xml' href='http://dave-black.blogspot.com/feeds/7846136791065305872/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://dave-black.blogspot.com/2019/04/missing-start-page-from-visual-studio.html#comment-form' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7674671342760410218/posts/default/7846136791065305872'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7674671342760410218/posts/default/7846136791065305872'/><link rel='alternate' type='text/html' href='http://dave-black.blogspot.com/2019/04/missing-start-page-from-visual-studio.html' title='Missing Start Page from Visual Studio 2019'/><author><name>Dave Black</name><uri>http://www.blogger.com/profile/11787334586939943513</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEghXqyOIYI80jcRqlgdIPg99-1bldyR6NKQgYGs8Uq_88qc_HNUrHXqM0R_9FvephlqkYzrrmMwMjSs7JV9QVSQAZMlO5hinHcLQrYmcSTRbCS-g4JIfIJaOYteBSxEzGhnZd9T8HJI2sJ86vEVB-Y_6XqfYX3CkdriJnePd8Yrnav-bw/s1600/linked-in-profile-pic-1743640118751.jfif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi9OzuyvvICU1sDS6Tlx7Vj0N_zv_qJ86s1rTu_MS054e8vzQnc2dAfcuhJO8VKPd8XE1K03RABmwFO9efY8r2i-5Oer-z6y33ds3IWxSp9WKWijnAU0s9FWl1CpaTcP4rBDB8c9wKHs8I/s72-c/startup.png" height="72" width="72"/><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7674671342760410218.post-1660528959478265565</id><published>2015-03-05T19:50:00.004-06:00</published><updated>2025-02-03T13:40:48.795-06:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="angular"/><category scheme="http://www.blogger.com/atom/ns#" term="Javascript"/><category scheme="http://www.blogger.com/atom/ns#" term="typescript"/><title type='text'>Angular2 and TypeScript</title><content type='html'>This is awesome for the Client side scripting world! I LOVE both of the languages and the features and safety of each. &amp;nbsp;Great collaboration!&lt;br /&gt;
&lt;br /&gt;
&lt;div&gt;
&lt;a href=&quot;http://techcrunch.com/2015/03/05/microsoft-and-google-collaborate-on-typescript-hell-has-not-frozen-over-yet/&quot; target=&quot;_blank&quot;&gt;Http://techcrunch.com/2015/03/05/microsoft-and-google-collaborate-on-typescript-hell-has-not-frozen-over-yet/&lt;/a&gt;&lt;/div&gt;
</content><link rel='replies' type='application/atom+xml' href='http://dave-black.blogspot.com/feeds/1660528959478265565/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://dave-black.blogspot.com/2015/03/angular2-and-typescript.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7674671342760410218/posts/default/1660528959478265565'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7674671342760410218/posts/default/1660528959478265565'/><link rel='alternate' type='text/html' href='http://dave-black.blogspot.com/2015/03/angular2-and-typescript.html' title='Angular2 and TypeScript'/><author><name>Dave Black</name><uri>http://www.blogger.com/profile/11787334586939943513</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEghXqyOIYI80jcRqlgdIPg99-1bldyR6NKQgYGs8Uq_88qc_HNUrHXqM0R_9FvephlqkYzrrmMwMjSs7JV9QVSQAZMlO5hinHcLQrYmcSTRbCS-g4JIfIJaOYteBSxEzGhnZd9T8HJI2sJ86vEVB-Y_6XqfYX3CkdriJnePd8Yrnav-bw/s1600/linked-in-profile-pic-1743640118751.jfif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7674671342760410218.post-2169378859026279839</id><published>2015-02-18T13:35:00.002-06:00</published><updated>2025-02-03T13:41:03.505-06:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="HTTP"/><title type='text'>HTTP 2 is finally done</title><content type='html'>Finally the specs for HTTP 2 were finalized yesterday and will be integrated into Chrome 40 and a new FireFox coming over the next 10-12 weeks. &amp;nbsp;Here are some of the things to expect.&lt;br /&gt;
&lt;br /&gt;
&lt;a href=&quot;http://thenextweb.com/insider/2015/02/18/http2-first-major-update-http-sixteen-years-finalized/&quot;&gt;http://thenextweb.com/insider/2015/02/18/http2-first-major-update-http-sixteen-years-finalized/&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;a href=&quot;https://www.mnot.net/blog/2014/01/30/http2_expectations&quot;&gt;https://www.mnot.net/blog/2014/01/30/http2_expectations&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;a href=&quot;http://gizmodo.com/what-is-http-2-1686537168&quot; target=&quot;_blank&quot;&gt;http://gizmodo.com/what-is-http-2-1686537168&lt;/a&gt;</content><link rel='replies' type='application/atom+xml' href='http://dave-black.blogspot.com/feeds/2169378859026279839/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://dave-black.blogspot.com/2015/02/http-2-is-finally-done.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7674671342760410218/posts/default/2169378859026279839'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7674671342760410218/posts/default/2169378859026279839'/><link rel='alternate' type='text/html' href='http://dave-black.blogspot.com/2015/02/http-2-is-finally-done.html' title='HTTP 2 is finally done'/><author><name>Dave Black</name><uri>http://www.blogger.com/profile/11787334586939943513</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEghXqyOIYI80jcRqlgdIPg99-1bldyR6NKQgYGs8Uq_88qc_HNUrHXqM0R_9FvephlqkYzrrmMwMjSs7JV9QVSQAZMlO5hinHcLQrYmcSTRbCS-g4JIfIJaOYteBSxEzGhnZd9T8HJI2sJ86vEVB-Y_6XqfYX3CkdriJnePd8Yrnav-bw/s1600/linked-in-profile-pic-1743640118751.jfif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7674671342760410218.post-8808122588116582865</id><published>2014-09-10T11:22:00.001-05:00</published><updated>2025-02-03T13:41:19.045-06:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="anti-pattern"/><category scheme="http://www.blogger.com/atom/ns#" term="Dependency Injection"/><title type='text'>How not to do Dependency Injection</title><content type='html'>Dependency Injection (DI) is not a new concept and has been discussed, blogged, and published many times.&amp;nbsp; There are a huge number of books out there on the subject.&amp;nbsp; I&#39;ve seen many usages and implementations of it used by various clients I&#39;ve consulted for.&amp;nbsp; &lt;br /&gt;
&lt;br /&gt;
Like the author of the blog post I refer to below, one of the most common and mis-used, abuses of, and antipatterns I&#39;ve seen is the wrapping of the DI model in a static container.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
I recently found an excellent article that explains in great detail why this is a bad idea and a big anti-pattern - &lt;a href=&quot;http://www.devtrends.co.uk/blog/how-not-to-do-dependency-injection-the-static-or-singleton-container&quot;&gt;http://www.devtrends.co.uk/blog/how-not-to-do-dependency-injection-the-static-or-singleton-container&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
Hopefully, this will help improve your understanding of what DI is and how it should &lt;strong&gt;not&lt;/strong&gt; be used.</content><link rel='replies' type='application/atom+xml' href='http://dave-black.blogspot.com/feeds/8808122588116582865/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://dave-black.blogspot.com/2014/09/how-not-to-do-dependency-injection.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7674671342760410218/posts/default/8808122588116582865'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7674671342760410218/posts/default/8808122588116582865'/><link rel='alternate' type='text/html' href='http://dave-black.blogspot.com/2014/09/how-not-to-do-dependency-injection.html' title='How not to do Dependency Injection'/><author><name>Dave Black</name><uri>http://www.blogger.com/profile/11787334586939943513</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEghXqyOIYI80jcRqlgdIPg99-1bldyR6NKQgYGs8Uq_88qc_HNUrHXqM0R_9FvephlqkYzrrmMwMjSs7JV9QVSQAZMlO5hinHcLQrYmcSTRbCS-g4JIfIJaOYteBSxEzGhnZd9T8HJI2sJ86vEVB-Y_6XqfYX3CkdriJnePd8Yrnav-bw/s1600/linked-in-profile-pic-1743640118751.jfif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7674671342760410218.post-9187973367876636110</id><published>2012-05-24T11:30:00.001-05:00</published><updated>2025-02-03T13:42:35.735-06:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="CLR"/><category scheme="http://www.blogger.com/atom/ns#" term="references"/><category scheme="http://www.blogger.com/atom/ns#" term="versioning"/><title type='text'>References to missing Types or Methods in referenced DLL</title><content type='html'>Ever wonder what happens if you have a binary reference to an external .dll and decide not to recompile the application or library that references/depends on it?  You can get some strange errors depending on the changes that have been made.

Ever experienced a &lt;span style=&quot;color: #2b91af; font-family: Courier New;&quot;&gt;BadImageFormatException, ExecutionEngineException, TypeLoadException, or MissingMethodException?&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
Firstly, the manifest file for the dependent app/library is not updated pointing to the new version.  This can cause mismatched assembly version errors (BadImageFormatException).

&lt;br /&gt;
&lt;br /&gt;
Here are the results from some tests with the removal of types and/or methods on a referenced assembly (hereinafter referred to as ‘Bad Assembly’).  All tests were done with x86 Console App/Library in separate solutions with a “static hardcoded” path reference to Bad Assembly (x64 shouldn’t matter):

&lt;br /&gt;
&lt;ol&gt;
&lt;li&gt;Results were always the same for Release/Debug builds.

&lt;/li&gt;
&lt;li&gt;The bad assembly was always successfully loaded.  ‘fuslogvw’ (.NET Assembly Load Viewer) confirmed this.

&lt;/li&gt;
&lt;li&gt;Setting the reference to Bad Assembly as “Specific Version” (using v1.0.0.0) and changing the version on Bad Assembly to v1.1.0.0 had no effect.  However, I didn’t try defining Bad Assembly in the “assemblies” section of the app.config.  It is &lt;em&gt;possible&lt;/em&gt; that would have given a different result.

&lt;/li&gt;
&lt;li&gt;References to a missing Type OR calls to a missing Method from Bad Assembly in &quot;&lt;span style=&quot;color: blue; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt; line-height: 115%; mso-ansi-language: EN-US; mso-bidi-language: AR-SA; mso-fareast-font-family: Calibri; mso-fareast-language: EN-US; mso-fareast-theme-font: minor-latin;&quot;&gt;static&lt;/span&gt;&lt;span style=&quot;font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt; line-height: 115%; mso-ansi-language: EN-US; mso-bidi-language: AR-SA; mso-fareast-font-family: Calibri; mso-fareast-language: EN-US; mso-fareast-theme-font: minor-latin;&quot;&gt; &lt;span style=&quot;color: blue;&quot;&gt;void&lt;/span&gt; Main()&quot; &lt;/span&gt;resulted in a&amp;nbsp;&quot;&lt;span style=&quot;font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt; line-height: 115%; mso-ansi-language: EN-US; mso-bidi-language: AR-SA; mso-fareast-font-family: Calibri; mso-fareast-language: EN-US; mso-fareast-theme-font: minor-latin;&quot;&gt;System.&lt;span style=&quot;color: #2b91af;&quot;&gt;ExecutionEngineException&quot;&lt;/span&gt;&lt;/span&gt; (fatal error as shown below).  This exception cannot be caught by any means: Assembly events, AppDomain events, try/catch block in &quot;&lt;span style=&quot;color: blue; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt; line-height: 115%; mso-ansi-language: EN-US; mso-bidi-language: AR-SA; mso-fareast-font-family: Calibri; mso-fareast-language: EN-US; mso-fareast-theme-font: minor-latin;&quot;&gt;static&lt;/span&gt;&lt;span style=&quot;font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt; line-height: 115%; mso-ansi-language: EN-US; mso-bidi-language: AR-SA; mso-fareast-font-family: Calibri; mso-fareast-language: EN-US; mso-fareast-theme-font: minor-latin;&quot;&gt; &lt;span style=&quot;color: blue;&quot;&gt;void&lt;/span&gt; Main()&quot;&lt;/span&gt;.  I confirmed this thru WinDbg.  This is because it is the first method that the EE (CLR Execution Engine) tells the JIT to compile.  Since JIT happens on a method-by-method basis and &quot;&lt;span style=&quot;color: blue; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt; line-height: 115%; mso-ansi-language: EN-US; mso-bidi-language: AR-SA; mso-fareast-font-family: Calibri; mso-fareast-language: EN-US; mso-fareast-theme-font: minor-latin;&quot;&gt;static&lt;/span&gt;&lt;span style=&quot;font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt; line-height: 115%; mso-ansi-language: EN-US; mso-bidi-language: AR-SA; mso-fareast-font-family: Calibri; mso-fareast-language: EN-US; mso-fareast-theme-font: minor-latin;&quot;&gt; &lt;span style=&quot;color: blue;&quot;&gt;void&lt;/span&gt; Main()&quot;&lt;/span&gt; is the entry point for the app, there is no place “upstream” where an exception can be caught.  The error in the Event Viewer is completely cryptic and provides no indication what went wrong.

&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: &amp;quot;Calibri&amp;quot;,&amp;quot;sans-serif&amp;quot;; font-size: 12pt; line-height: 115%; mso-ansi-language: EN-US; mso-ascii-theme-font: minor-latin; mso-bidi-font-family: &amp;quot;Times New Roman&amp;quot;; mso-bidi-language: AR-SA; mso-bidi-theme-font: minor-bidi; mso-fareast-font-family: Calibri; mso-fareast-language: EN-US; mso-fareast-theme-font: minor-latin; mso-hansi-theme-font: minor-latin;&quot;&gt;If
the reference to a missing Type OR calls to a missing Method from Bad Assembly
occurred “downstream” of &quot;&lt;/span&gt;&lt;span style=&quot;color: blue; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt; line-height: 115%; mso-ansi-language: EN-US; mso-bidi-language: AR-SA; mso-fareast-font-family: Calibri; mso-fareast-language: EN-US; mso-fareast-theme-font: minor-latin;&quot;&gt;static&lt;/span&gt;&lt;span style=&quot;font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt; line-height: 115%; mso-ansi-language: EN-US; mso-bidi-language: AR-SA; mso-fareast-font-family: Calibri; mso-fareast-language: EN-US; mso-fareast-theme-font: minor-latin;&quot;&gt; &lt;span style=&quot;color: blue;&quot;&gt;void&lt;/span&gt; Main()&quot;&lt;/span&gt;&lt;span style=&quot;font-family: &amp;quot;Calibri&amp;quot;,&amp;quot;sans-serif&amp;quot;; font-size: 11pt; line-height: 115%; mso-ansi-language: EN-US; mso-ascii-theme-font: minor-latin; mso-bidi-font-family: &amp;quot;Times New Roman&amp;quot;; mso-bidi-language: AR-SA; mso-bidi-theme-font: minor-bidi; mso-fareast-font-family: Calibri; mso-fareast-language: EN-US; mso-fareast-theme-font: minor-latin; mso-hansi-theme-font: minor-latin;&quot;&gt; AND there WAS NOT exception handling upstream,
OR there WAS exception handling upstream but the exception was rethrown so that
is was never caught again, then results were same as #4.&amp;nbsp; (i.e. unhandled
exception)&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: &amp;quot;Calibri&amp;quot;,&amp;quot;sans-serif&amp;quot;; font-size: 12pt; line-height: 115%; mso-ansi-language: EN-US; mso-ascii-theme-font: minor-latin; mso-bidi-font-family: &amp;quot;Times New Roman&amp;quot;; mso-bidi-language: AR-SA; mso-bidi-theme-font: minor-bidi; mso-fareast-font-family: Calibri; mso-fareast-language: EN-US; mso-fareast-theme-font: minor-latin; mso-hansi-theme-font: minor-latin;&quot;&gt;If
the reference to a missing Type OR calls to a missing Method from Bad Assembly
occurred “downstream” of &quot;&lt;/span&gt;&lt;span style=&quot;color: blue; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt; line-height: 115%; mso-ansi-language: EN-US; mso-bidi-language: AR-SA; mso-fareast-font-family: Calibri; mso-fareast-language: EN-US; mso-fareast-theme-font: minor-latin;&quot;&gt;static&lt;/span&gt;&lt;span style=&quot;font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt; line-height: 115%; mso-ansi-language: EN-US; mso-bidi-language: AR-SA; mso-fareast-font-family: Calibri; mso-fareast-language: EN-US; mso-fareast-theme-font: minor-latin;&quot;&gt; &lt;span style=&quot;color: blue;&quot;&gt;void&lt;/span&gt; Main()&quot;&lt;/span&gt;&lt;span style=&quot;font-family: &amp;quot;Calibri&amp;quot;,&amp;quot;sans-serif&amp;quot;; font-size: 11pt; line-height: 115%; mso-ansi-language: EN-US; mso-ascii-theme-font: minor-latin; mso-bidi-font-family: &amp;quot;Times New Roman&amp;quot;; mso-bidi-language: AR-SA; mso-bidi-theme-font: minor-bidi; mso-fareast-font-family: Calibri; mso-fareast-language: EN-US; mso-fareast-theme-font: minor-latin; mso-hansi-theme-font: minor-latin;&quot;&gt; AND there WAS exception handling upstream, then
the exception was caught as either a &quot;&lt;/span&gt;&lt;span style=&quot;font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt; line-height: 115%; mso-ansi-language: EN-US; mso-bidi-language: AR-SA; mso-fareast-font-family: Calibri; mso-fareast-language: EN-US; mso-fareast-theme-font: minor-latin;&quot;&gt;System.&lt;span style=&quot;color: #2b91af;&quot;&gt;TypeLoadException&quot;&lt;/span&gt;
or &quot;System.&lt;span style=&quot;color: #2b91af;&quot;&gt;MissingMethodException&quot;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;font-family: &amp;quot;Calibri&amp;quot;,&amp;quot;sans-serif&amp;quot;; font-size: 11pt; line-height: 115%; mso-ansi-language: EN-US; mso-ascii-theme-font: minor-latin; mso-bidi-font-family: &amp;quot;Times New Roman&amp;quot;; mso-bidi-language: AR-SA; mso-bidi-theme-font: minor-bidi; mso-fareast-font-family: Calibri; mso-fareast-language: EN-US; mso-fareast-theme-font: minor-latin; mso-hansi-theme-font: minor-latin;&quot;&gt; respectively.&amp;nbsp; The exceptions were thrown
from the JIT as the Type or Method was accessed.&lt;/span&gt;&lt;span style=&quot;font-family: &amp;quot;Calibri&amp;quot;,&amp;quot;sans-serif&amp;quot;; font-size: 11pt; line-height: 115%; mso-ansi-language: EN-US; mso-ascii-theme-font: minor-latin; mso-bidi-font-family: &amp;quot;Times New Roman&amp;quot;; mso-bidi-language: AR-SA; mso-bidi-theme-font: minor-bidi; mso-fareast-font-family: Calibri; mso-fareast-language: EN-US; mso-fareast-theme-font: minor-latin; mso-hansi-theme-font: minor-latin;&quot;&gt;&lt;/span&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgTyj2WHB4qErgbOnD8LSbuQ520hBFJ17DryIGsUV0Axckv-Gbp1CbjUVUvSZiAkrwdQ3QyKAwEB8PaxWoGHNlO67V5X7LpkMBaL8ziWnpH3O-HiIUpghfniSQ57QHWqrob20o_F9R2KSs/s1600/testConsoleStoppedWorking1.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;154&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgTyj2WHB4qErgbOnD8LSbuQ520hBFJ17DryIGsUV0Axckv-Gbp1CbjUVUvSZiAkrwdQ3QyKAwEB8PaxWoGHNlO67V5X7LpkMBaL8ziWnpH3O-HiIUpghfniSQ57QHWqrob20o_F9R2KSs/s320/testConsoleStoppedWorking1.png&quot; width=&quot;320&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhx1uY5u-tj_AX8qANYhfjnNUSJmR3ehTNLZ8dTNdeui4lOLF3zeikAywU3wTbT20ey5PQSIYxClXVb8uEWgT0AaVYcUGq0BWl1V7Si0lTSY7czZ1S7ROZ-D4sCitm0cPHrzbmF6cZMkgI/s1600/testConsoleStoppedWorking2.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;159&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhx1uY5u-tj_AX8qANYhfjnNUSJmR3ehTNLZ8dTNdeui4lOLF3zeikAywU3wTbT20ey5PQSIYxClXVb8uEWgT0AaVYcUGq0BWl1V7Si0lTSY7czZ1S7ROZ-D4sCitm0cPHrzbmF6cZMkgI/s320/testConsoleStoppedWorking2.png&quot; width=&quot;320&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
HTH&lt;br /&gt;
&lt;br /&gt;</content><link rel='replies' type='application/atom+xml' href='http://dave-black.blogspot.com/feeds/9187973367876636110/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://dave-black.blogspot.com/2012/05/references-to-missing-types-or-methods.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7674671342760410218/posts/default/9187973367876636110'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7674671342760410218/posts/default/9187973367876636110'/><link rel='alternate' type='text/html' href='http://dave-black.blogspot.com/2012/05/references-to-missing-types-or-methods.html' title='References to missing Types or Methods in referenced DLL'/><author><name>Dave Black</name><uri>http://www.blogger.com/profile/11787334586939943513</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEghXqyOIYI80jcRqlgdIPg99-1bldyR6NKQgYGs8Uq_88qc_HNUrHXqM0R_9FvephlqkYzrrmMwMjSs7JV9QVSQAZMlO5hinHcLQrYmcSTRbCS-g4JIfIJaOYteBSxEzGhnZd9T8HJI2sJ86vEVB-Y_6XqfYX3CkdriJnePd8Yrnav-bw/s1600/linked-in-profile-pic-1743640118751.jfif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgTyj2WHB4qErgbOnD8LSbuQ520hBFJ17DryIGsUV0Axckv-Gbp1CbjUVUvSZiAkrwdQ3QyKAwEB8PaxWoGHNlO67V5X7LpkMBaL8ziWnpH3O-HiIUpghfniSQ57QHWqrob20o_F9R2KSs/s72-c/testConsoleStoppedWorking1.png" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7674671342760410218.post-133297541659442113</id><published>2012-05-18T09:42:00.010-05:00</published><updated>2025-02-03T13:43:08.734-06:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="best practices"/><category scheme="http://www.blogger.com/atom/ns#" term="performance"/><title type='text'>Why you should use ReadOnlyCollection&amp;lt;T&amp;gt;</title><content type='html'>Many people believe that you should be using &lt;code&gt;List&amp;lt;T&amp;gt;&lt;/code&gt; to return collections from a public API. However, there are several reasons not to do so; instead return a &lt;code&gt;ReadOnlyCollection&amp;lt;T&amp;gt;&lt;/code&gt;. The are several benefits of 
using a &lt;code&gt;ReadOnlyCollection&amp;lt;T&amp;gt;&lt;/code&gt;:
&lt;br /&gt;
&lt;ol&gt;
&lt;li&gt;The &lt;b&gt;*collection itself&lt;/b&gt;* cannot be modified - i.e. you 
cannot add, remove, or replace any item in the collection. So, it keeps the 
collection itself intact. Note that a &lt;code&gt;ReadOnlyCollection&amp;lt;T&amp;gt;&lt;/code&gt; does not mean that the elements within the collection are &quot;readonly&quot;; they can still be modified. To protect 
the items in it, you’d probably have to have private “setters” on any properties 
for the reference object in the collection – which is generally recommended.  
However, items that are declared as &lt;code&gt;[DataMember]&lt;/code&gt; must have both public getters 
and setters. So if you are in that case, you can’t do the private setter, but 
you can still use the &lt;code&gt;ReadOnlyCollection&amp;lt;T&amp;gt;&lt;/code&gt;.  Using this as a Design 
paradigm can prevent subtle bugs from popping up. One case that comes to mind is the case of a &lt;code&gt;HashSet&amp;lt;T&amp;gt;&lt;/code&gt;. It is recommended to avoid having mutable properties on &lt;code&gt;class&lt;/code&gt; or &lt;code&gt;struct&lt;/code&gt; types that are going to be used in any collection that utilizes the types hash code to refer to an object of that type - e.g. &lt;code&gt;HashSet&amp;lt;T&amp;gt;&lt;/code&gt;, 
  
  
&lt;/li&gt;
  &lt;li&gt;Performance: The &lt;code&gt;List&amp;lt;T&amp;gt;&lt;/code&gt; class is essentially a wrapper around a strongly-typed array. Since arrays are  immutable (cannot be re-sized), any modifications made to a &lt;code&gt;List&amp;lt;T&amp;gt;&lt;/code&gt; must  create a complete copy of the &lt;code&gt;List&amp;lt;T&amp;gt;&lt;/code&gt; and add the new item. Note that in the case of value types, a copy of the value type is created whereas, in the case of reference types, a copy of the reference to the object is created. The performance impact for reference types is negligible.
    
    The initial capacity for a &lt;code&gt;List&amp;lt;T&amp;gt;&lt;/code&gt; is 4 unless specified thru the overloaded constructor - see &lt;a href=&quot;https://github.com/dotnet/runtime/blob/1d1bf92fcf43aa6981804dc53c5174445069c9e4/src/libraries/System.Private.CoreLib/src/System/Collections/Generic/List.cs#L23&quot; target=&quot;_blank&quot;&gt;here&lt;/a&gt;. 
    
    
    https://learn.microsoft.com/en-us/dotnet/api/system.runtime.interopservices.collectionsmarshal.getvaluereforadddefault
    
    
    Obviously, this can be very bad for memory and performance. Don’t forget that not only the items directly within the &lt;code&gt;List&amp;lt;T&amp;gt;&lt;/code&gt;
    itself are copied – but every value and object with the entire object graph for that reference type. 
    This could easily contain other references types, collections, etc. This is why it is recommended to create/initialize a &lt;code&gt;List&amp;lt;T&amp;gt;&lt;/code&gt; instance with the overloaded constructor which takes an &lt;code&gt;int&lt;/code&gt; denoting the size of the &lt;code&gt;List&amp;lt;T&amp;gt;&lt;/code&gt; to be created when possible. This can often be done since you are typically iterating on a &quot;known&quot; size value at runtime. For example, creating a &lt;code&gt;List&amp;lt;T&amp;gt;&lt;/code&gt; of objects from a &quot;Repository or DataService&quot; method may iterate/read from a &lt;code&gt;IDataReader&lt;/code&gt; object which has a property of &lt;code&gt;RecordsAffected&lt;/code&gt;. If you are going to be putting an item in the &lt;code&gt;List&amp;lt;T&amp;gt;&lt;/code&gt; based on the number of times the &lt;code&gt;IDataReader&lt;/code&gt; is read: e.g. &lt;code&gt;while(reader.Read())&lt;/code&gt; you can easily create the list like so:
&lt;/li&gt;
&lt;/ol&gt;

&lt;pre&gt;&lt;code&gt;if (reader != null &amp;amp;&amp;amp; reader.RecordsAffected &gt; 0)
{
    // initialize the list with a pre-defined size
    List&amp;lt;Foo&amp;gt; someList = new List&amp;lt;Foo&amp;gt;(reader.RecordsAffected);
    while (reader.Read())
    {
         someList.Add(...);
         ...
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;br /&gt;
Just as a side note, every time 
that a &lt;code&gt;List&amp;lt;T&amp;gt;&lt;/code&gt; needs to grow in size (its new size would exceed its current &lt;code&gt;Capactity&lt;/code&gt;, &lt;a href=&quot;https://github.com/dotnet/runtime/blob/1d1bf92fcf43aa6981804dc53c5174445069c9e4/src/libraries/System.Private.CoreLib/src/System/Collections/Generic/List.cs#L492&quot; target=&quot;_blank&quot;&gt;the size is *&lt;b&gt;doubled&lt;/b&gt;*&lt;/a&gt;.  So, 
if you happen to add just one more item to a &lt;code&gt;List&amp;lt;T&amp;gt;&lt;/code&gt; that wasn’t 
constructed with a pre-determined size, and the &lt;code&gt;List&amp;lt;T&amp;gt;&lt;/code&gt; expands to 
accommodate the new item, there will be a whole lot of unused space at the end 
of the &lt;code&gt;List&amp;lt;T&amp;gt;&lt;/code&gt; even though there aren’t any items in it – bad for memory 
and performance.
</content><link rel='replies' type='application/atom+xml' href='http://dave-black.blogspot.com/feeds/133297541659442113/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://dave-black.blogspot.com/2012/05/why-you-should-use-readonlycollection.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7674671342760410218/posts/default/133297541659442113'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7674671342760410218/posts/default/133297541659442113'/><link rel='alternate' type='text/html' href='http://dave-black.blogspot.com/2012/05/why-you-should-use-readonlycollection.html' title='Why you should use ReadOnlyCollection&amp;lt;T&amp;gt;'/><author><name>Dave Black</name><uri>http://www.blogger.com/profile/11787334586939943513</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEghXqyOIYI80jcRqlgdIPg99-1bldyR6NKQgYGs8Uq_88qc_HNUrHXqM0R_9FvephlqkYzrrmMwMjSs7JV9QVSQAZMlO5hinHcLQrYmcSTRbCS-g4JIfIJaOYteBSxEzGhnZd9T8HJI2sJ86vEVB-Y_6XqfYX3CkdriJnePd8Yrnav-bw/s1600/linked-in-profile-pic-1743640118751.jfif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7674671342760410218.post-4470009191254850403</id><published>2012-05-17T18:26:00.001-05:00</published><updated>2025-02-03T13:43:33.156-06:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="anti-pattern"/><category scheme="http://www.blogger.com/atom/ns#" term="best practices"/><title type='text'>Don&#39;t implement GetHashCode() on mutable fields/properties</title><content type='html'>&lt;a href=&quot;http://www.codeproject.com/script/Articles/BlogFeedList.aspx?amid=3680616&quot; rel=&quot;GetHashCode&quot; style=&quot;display:none&quot;&gt;CodeProject&lt;/a&gt;
You shouldn&#39;t ever implement GetHashCode on mutable properties (properties that could be changed by someone) - i.e. non-private setters. &amp;nbsp; I&#39;ve seen this done in several places and it results in very difficult to find bugs.&lt;br /&gt;
&lt;br /&gt;
Here&#39;s why - imagine this scenario: &lt;br /&gt;
&lt;ol&gt;
&lt;li&gt;You put an instance of your object in a collection which uses GetHashCode() &quot;under the covers&quot; or directly (Hashtable). &lt;/li&gt;
&lt;li&gt;Then someone changes the value of the field/property that you&#39;ve used in your GetHashCode() implementation.  &lt;/li&gt;
&lt;/ol&gt;
Guess what...your object is permanently lost in the collection since the collection uses GetHashCode() to find it!  You&#39;ve effectively changed the hashcode value from what was originally placed in the collection.  Probably not what you wanted.</content><link rel='replies' type='application/atom+xml' href='http://dave-black.blogspot.com/feeds/4470009191254850403/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://dave-black.blogspot.com/2012/05/dont-implement-gethashcode-on-mutable.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7674671342760410218/posts/default/4470009191254850403'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7674671342760410218/posts/default/4470009191254850403'/><link rel='alternate' type='text/html' href='http://dave-black.blogspot.com/2012/05/dont-implement-gethashcode-on-mutable.html' title='Don&#39;t implement GetHashCode() on mutable fields/properties'/><author><name>Dave Black</name><uri>http://www.blogger.com/profile/11787334586939943513</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEghXqyOIYI80jcRqlgdIPg99-1bldyR6NKQgYGs8Uq_88qc_HNUrHXqM0R_9FvephlqkYzrrmMwMjSs7JV9QVSQAZMlO5hinHcLQrYmcSTRbCS-g4JIfIJaOYteBSxEzGhnZd9T8HJI2sJ86vEVB-Y_6XqfYX3CkdriJnePd8Yrnav-bw/s1600/linked-in-profile-pic-1743640118751.jfif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7674671342760410218.post-1004176432994179108</id><published>2012-04-17T15:34:00.003-05:00</published><updated>2025-02-03T13:50:12.881-06:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="debugging"/><category scheme="http://www.blogger.com/atom/ns#" term="gc"/><category scheme="http://www.blogger.com/atom/ns#" term="memory management"/><category scheme="http://www.blogger.com/atom/ns#" term="windbg"/><title type='text'>How to determine which garbage collector is running</title><content type='html'>&lt;a href=&quot;http://www.codeproject.com/script/Articles/BlogFeedList.aspx?amid=3680616&quot; rel=&quot;GC,garbage collect&quot; style=&quot;display: none;&quot;&gt;CodeProject&lt;/a&gt;You can determine which version of GC you&#39;re running via 2 methods: &lt;br /&gt;
&lt;ol&gt;
&lt;li&gt;calling the System.Runtime.GCSettings.IsServerGC property &lt;/li&gt;
&lt;li&gt;attaching to the process using WinDbg and checking how many GC threads you have using the command &quot;!sos.threads&quot; without the quotes and (according to the below criteria)... &lt;/li&gt;
&lt;/ol&gt;
If you are running a Console app, WinForm app or a Windows Service, you will get the Workstation GC. &lt;strong&gt;Just because you are running on a Server OS doesn&#39;t mean that you will get the Server version of GC&lt;/strong&gt;. &lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;If your app is non-hosted on a multi-proc machine, you will get the Workstation GC - Concurrent by default. &lt;/li&gt;
&lt;li&gt;If your app is hosted on a multi-proc machine, you will get the ServerGC by default.&lt;/li&gt;
&lt;/ul&gt;
The following apply to any given .NET Managed Process:&lt;br /&gt;
&lt;h3&gt;
Workstation GC&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Uni-processor machine&lt;/li&gt;
&lt;li&gt;Always suspends threads &lt;/li&gt;
&lt;li&gt;1 Ephemeral GC Heap (SOH), 1 LOH GC Heap &lt;/li&gt;
&lt;li&gt;Runs on thread that triggered GC &lt;/li&gt;
&lt;li&gt;Thread priority is the same as the thread that triggered GC &lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
Workstation GC - Concurrent&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Only runs concurrent in Gen2/LOH (full collection)&lt;/li&gt;
&lt;li&gt;Mutually exclusive with Server Mode&lt;/li&gt;
&lt;li&gt;Slightly larger working set &lt;/li&gt;
&lt;li&gt;GC Thread expires if not in use after a while&lt;/li&gt;
&lt;li&gt;1 Ephemeral GC Heap (SOH), 1 LOH GC Heap&lt;/li&gt;
&lt;li&gt;Has a dedicated GC Thread &lt;/li&gt;
&lt;li&gt;Thread priority is Normal &lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
Server GC &lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Larger segment sizes &lt;/li&gt;
&lt;li&gt;Faster than Workstation GC&lt;/li&gt;
&lt;li&gt;Always suspends threads &lt;/li&gt;
&lt;li&gt;1 Ephemeral GC Heap (SOH) for each logical processor (this includes hyperthreaded), 1 LOH GC Heap for each logical processor (this includes hyperthreaded)&lt;/li&gt;
&lt;li&gt;Has dedicated GC Threads &lt;/li&gt;
&lt;li&gt;Thread priority is THREAD_PRIORITY_HIGHEST&lt;/li&gt;
&lt;/ul&gt;
There is only 1 Finalizer thread per managed process regardless of GC Mode. Even during a concurrent GC, managed threads are suspended (blocked) twice to do some phases of the GC.&lt;br /&gt;
&lt;br /&gt;
&lt;strong&gt;A seldom known fact&lt;/strong&gt; is that even if you try to set the Server mode of GC, you might not be running in Server GC; the GC ultimately determines which mode will be optimal for your app and WILL override your settings if it determines your ServerGC setting will negatively impact your application. Also, any hosted CLR app will have any manual GC settings overridden.&lt;br /&gt;
&lt;br /&gt;
&lt;h3&gt;
In CLR 4.0, things change just a little bit&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt; Concurrent GC is now Background GC&lt;/li&gt;
&lt;li&gt;Background GC only applies to Workstation GC&lt;/li&gt;
&lt;li&gt;Old (Concurrent GC): &lt;/li&gt;
&lt;ul&gt;
&lt;li&gt;During a Full GC Allowed allocations up to end of ephemeral segment size &lt;/li&gt;
&lt;li&gt;Otherwise, suspends all other threads &lt;/li&gt;
&lt;/ul&gt;
&lt;li&gt;New (Background GC): &lt;/li&gt;
&lt;ul&gt;
&lt;li&gt;Allows for ephemeral GC’s simultaneously with Background GC if necessary &lt;/li&gt;
&lt;li&gt;Performance is much faster&lt;/li&gt;
&lt;/ul&gt;
&lt;li&gt;Server GC always blocks threads for collection of any generation&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
In CLR 4.5, things change just a little bit...again&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Background Server GC&lt;/li&gt;
&lt;ul&gt;
&lt;li&gt;Server GC no longer blocks. Instead, it uses dedicated background GC threads that can run concurrently with user code - see &lt;a href=&quot;http://msdn.microsoft.com/library/ee787088(v=vs.110).aspx#background_server_garbage_collection&quot; target=&quot;_blank&quot;&gt;MSDN: Background Server GC&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/ul&gt;
Thus, in .NET 4.5+, all applications now have background GC &lt;em&gt;available&lt;/em&gt; to them, regardless of which GC they use. &lt;br /&gt;
&lt;br /&gt;
&lt;h3&gt;
.NET 4.7.1 GC Improvements&lt;/h3&gt;
&lt;div&gt;
.NET Framework 4.7.1 brings in changes in Garbage Collection (GC) to improve the allocation performance, especially for Large Object Heap (LOH) allocations. This is due to an architectural change to split the heap’s allocation lock into 2, for Small Object Heap (SOH) and LOH. Applications that make a lot of LOH allocations, should see a reduction in allocation lock contention, and see better performance. These improvements allow LOH allocations while Background GC (BGC) is sweeping SOH. Usually the LOH allocator waits for the whole duration of the BGC sweep process before it can satisfy requests to allocate memory. This can hinder performance. You can observe this problem in PerfView’s GCStats where there is an ‘LOH allocation pause (due to background GC) &amp;gt; 200 msec Events’ table. The pause reason is ‘Waiting for BGC to thread free lists’. This feature should help mitigate this problem.&lt;/div&gt;
</content><link rel='replies' type='application/atom+xml' href='http://dave-black.blogspot.com/feeds/1004176432994179108/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://dave-black.blogspot.com/2012/04/how-to-determine-which-garbage.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7674671342760410218/posts/default/1004176432994179108'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7674671342760410218/posts/default/1004176432994179108'/><link rel='alternate' type='text/html' href='http://dave-black.blogspot.com/2012/04/how-to-determine-which-garbage.html' title='How to determine which garbage collector is running'/><author><name>Dave Black</name><uri>http://www.blogger.com/profile/11787334586939943513</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEghXqyOIYI80jcRqlgdIPg99-1bldyR6NKQgYGs8Uq_88qc_HNUrHXqM0R_9FvephlqkYzrrmMwMjSs7JV9QVSQAZMlO5hinHcLQrYmcSTRbCS-g4JIfIJaOYteBSxEzGhnZd9T8HJI2sJ86vEVB-Y_6XqfYX3CkdriJnePd8Yrnav-bw/s1600/linked-in-profile-pic-1743640118751.jfif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7674671342760410218.post-1682972752280578456</id><published>2012-03-13T16:07:00.001-05:00</published><updated>2025-02-03T13:44:06.388-06:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="best practices"/><category scheme="http://www.blogger.com/atom/ns#" term="dispose"/><title type='text'>Don&#39;t use &#39;using()&#39; with a WCF proxy</title><content type='html'>&lt;a href=&quot;http://www.codeproject.com/script/Articles/BlogFeedList.aspx?amid=3680616&quot; rel=&quot;tag&quot; style=&quot;display: none;&quot;&gt;CodeProject&lt;/a&gt;&lt;br /&gt;
&lt;div class=&quot;tr_bq&quot;&gt;
If you&#39;re trying to be a conscientious developer and making sure that you cleanup your resources - great!  You are writing &#39;using()&#39; blocks around all of your disposable items - great...except when the disposable item is a WCF Client/Proxy!

The using() statement and the try/finally effectively have the same IL:

&lt;/div&gt;
&lt;div style=&quot;border: 1px solid rgb(0, 0, 128); font-family: &#39;courier new&#39;, courier, monospace; font-size: 10pt;&quot;&gt;
&lt;div style=&quot;background-color: #d6d6d6; overflow: auto; padding: 2px 5px;&quot;&gt;
&lt;div style=&quot;color: black;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;color: green;&quot;&gt;
&amp;nbsp; &amp;nbsp; // The IL for this block is effectively the same as &lt;/div&gt;
&lt;div style=&quot;color: black;&quot;&gt;
&lt;span style=&quot;color: green; font-size: 10pt;&quot;&gt;&amp;nbsp; &amp;nbsp; // the IL for the second block below&lt;/span&gt;&lt;/div&gt;
&lt;div style=&quot;color: black;&quot;&gt;
&lt;span style=&quot;color: blue; font-size: 10pt;&quot;&gt;&amp;nbsp; &amp;nbsp; using&lt;/span&gt;&lt;span style=&quot;font-size: 10pt;&quot;&gt; (&lt;/span&gt;&lt;span style=&quot;color: blue; font-size: 10pt;&quot;&gt;var&lt;/span&gt;&lt;span style=&quot;font-size: 10pt;&quot;&gt; win = &lt;/span&gt;&lt;span style=&quot;color: blue; font-size: 10pt;&quot;&gt;new&lt;/span&gt;&lt;span style=&quot;font-size: 10pt;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #2b91af; font-size: 10pt;&quot;&gt;Form&lt;/span&gt;&lt;span style=&quot;font-size: 10pt;&quot;&gt;())&lt;/span&gt;&lt;/div&gt;
&lt;div style=&quot;color: black;&quot;&gt;
&lt;span style=&quot;font-size: 10pt;&quot;&gt;&amp;nbsp; &amp;nbsp; {&lt;/span&gt;&lt;/div&gt;
&lt;div style=&quot;color: black;&quot;&gt;
&lt;span style=&quot;font-size: 10pt;&quot;&gt;&amp;nbsp; &amp;nbsp; }&lt;/span&gt;&lt;/div&gt;
&lt;div style=&quot;color: black;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;color: black;&quot;&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/div&gt;
&lt;div style=&quot;color: green;&quot;&gt;
&amp;nbsp; &amp;nbsp; // This is the second block&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;color: #2b91af; font-size: 10pt;&quot;&gt;&amp;nbsp; &amp;nbsp; Form&lt;/span&gt;&lt;span style=&quot;color: black; font-size: 10pt;&quot;&gt; f = &lt;/span&gt;&lt;span style=&quot;color: blue; font-size: 10pt;&quot;&gt;null&lt;/span&gt;&lt;span style=&quot;color: black; font-size: 10pt;&quot;&gt;;&lt;/span&gt;&lt;/div&gt;
&lt;div style=&quot;color: black;&quot;&gt;
&lt;div&gt;
&lt;span style=&quot;color: blue;&quot;&gt;&amp;nbsp; &amp;nbsp; try&lt;/span&gt;&lt;/div&gt;
&lt;div style=&quot;color: black;&quot;&gt;
&lt;div&gt;
&amp;nbsp; &amp;nbsp; {&lt;/div&gt;
&lt;div style=&quot;color: black;&quot;&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; f = &lt;span style=&quot;color: blue;&quot;&gt;new&lt;/span&gt; &lt;span style=&quot;color: #2b91af;&quot;&gt;Form&lt;/span&gt;();&lt;/div&gt;
&lt;div style=&quot;color: black;&quot;&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;/div&gt;
&lt;div style=&quot;color: black;&quot;&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style=&quot;color: blue;&quot;&gt;finally&lt;/span&gt;&lt;/div&gt;
&lt;div style=&quot;color: black;&quot;&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;/div&gt;
&lt;div style=&quot;color: black;&quot;&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style=&quot;color: blue;&quot;&gt;if&lt;/span&gt; (f != &lt;span style=&quot;color: blue;&quot;&gt;null&lt;/span&gt;)&lt;/div&gt;
&lt;div style=&quot;color: black;&quot;&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;/div&gt;
&lt;div style=&quot;color: black;&quot;&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;f.Dispose();&lt;/div&gt;
&lt;div style=&quot;color: black;&quot;&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;/div&gt;
&lt;div style=&quot;color: black;&quot;&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;br /&gt;
Here&#39;s the IL for the &#39;using()&#39; block above compiled in Release mode:
&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp; &amp;nbsp; IL_0000:&amp;nbsp; newobj&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; instance void [System.Windows.Forms]System.Windows.Forms.Form::.ctor()&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; IL_0005:&amp;nbsp; stloc.0&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; .try&lt;br /&gt;
&amp;nbsp; &amp;nbsp;&amp;nbsp; {&lt;br /&gt;
&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; IL_0006:&amp;nbsp; leave.s&amp;nbsp;&amp;nbsp;&amp;nbsp; IL_0012&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&amp;nbsp; // end .try&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; finally&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; IL_0008:&amp;nbsp; ldloc.0&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; IL_0009:&amp;nbsp; brfalse.s&amp;nbsp; IL_0011&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp; IL_000b:&amp;nbsp; ldloc.0&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp; IL_000c:&amp;nbsp; callvirt&amp;nbsp;&amp;nbsp; instance void [mscorlib]System.IDisposable::Dispose()&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; IL_0011:&amp;nbsp; endfinally&lt;br /&gt;
&amp;nbsp; &amp;nbsp;&amp;nbsp; }&amp;nbsp; // end handler&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Here&#39;s the IL for the second block (try/finally) compiled in Release mode:&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; IL_0012:&amp;nbsp; ldnull&lt;br /&gt;
&amp;nbsp; &amp;nbsp;&amp;nbsp; IL_0013:&amp;nbsp; stloc.1&lt;br /&gt;
&amp;nbsp; &amp;nbsp;&amp;nbsp; .try&lt;br /&gt;
&amp;nbsp; &amp;nbsp;&amp;nbsp; {&lt;br /&gt;
&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; IL_0014:&amp;nbsp; newobj&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; instance void [System.Windows.Forms]System.Windows.Forms.Form::.ctor()&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp; IL_0019:&amp;nbsp; stloc.1&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp; IL_001a:&amp;nbsp; leave.s&amp;nbsp;&amp;nbsp;&amp;nbsp; IL_0026&lt;br /&gt;
&amp;nbsp; &amp;nbsp;&amp;nbsp; }&amp;nbsp; // end .try&lt;br /&gt;
&amp;nbsp; &amp;nbsp;&amp;nbsp; finally&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; IL_001c:&amp;nbsp; ldloc.1&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp; IL_001d:&amp;nbsp; brfalse.s&amp;nbsp; IL_0025&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; IL_001f:&amp;nbsp; ldloc.1&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; IL_0020:&amp;nbsp; callvirt&amp;nbsp;&amp;nbsp; instance void [System]System.ComponentModel.Component::Dispose()&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp; IL_0025:&amp;nbsp; endfinally&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&amp;nbsp; // end handler&lt;br /&gt;
&lt;br /&gt;
As you can see, the IL is nearly identical.&lt;br /&gt;
&lt;br /&gt;
Well this is all fine and good but let&#39;s get back to the issue with WCF.&amp;nbsp; The problem is that if an exception is thrown during disposal of the WCF client/proxy, the channel is never closed.&amp;nbsp; Now, in general, any exception that occurs during disposal of an object is indeed undesirable.&amp;nbsp; But, in the case of WCF, multiple channels remaining open could easily cause your entire service to fall on its face - not to mention what might eventually happen to your web server.&lt;br /&gt;
&lt;br /&gt;
Here is an alternative solution that can be used:&lt;br /&gt;
&lt;br /&gt;
&lt;div style=&quot;border: #000080 1px solid; color: black; font-family: &#39;Courier New&#39;, Courier, Monospace; font-size: 10pt;&quot;&gt;
&lt;div style=&quot;background-color: #d6d6d6; overflow: auto; padding: 2px 5px;&quot;&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style=&quot;color: red;&quot;&gt;WCFProxy&lt;/span&gt; variableName = &lt;span style=&quot;color: blue;&quot;&gt;null&lt;/span&gt;;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style=&quot;color: blue;&quot;&gt;try&lt;/span&gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;variableName = &lt;span style=&quot;color: blue;&quot;&gt;new&lt;/span&gt; &lt;span style=&quot;color: red;&quot;&gt;WCFProxy&lt;/span&gt;();&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style=&quot;color: green;&quot;&gt;// &lt;/span&gt;&lt;span style=&quot;color: darkblue;&quot;&gt;TODO code here&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;variableName&lt;span style=&quot;color: red;&quot;&gt;&lt;/span&gt;.Close();&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;
&lt;span style=&quot;color: green;&quot;&gt;// if you need to catch other exceptions, do so here...&lt;/span&gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style=&quot;color: blue;&quot;&gt;catch&lt;/span&gt; (&lt;span style=&quot;color: #2b91af;&quot;&gt;Exception&lt;/span&gt;)&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style=&quot;color: blue;&quot;&gt;if&lt;/span&gt; (variableName != &lt;span style=&quot;color: blue;&quot;&gt;null&lt;/span&gt;)&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br /&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;variableName.Abort();&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style=&quot;color: blue;&quot;&gt;throw&lt;/span&gt;;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;/div&gt;
&lt;/div&gt;
&lt;br /&gt;
MSDN does have a brief on this issue which you can read here - &lt;a href=&quot;http://msdn.microsoft.com/en-us/library/aa355056.aspx&quot;&gt;http://msdn.microsoft.com/en-us/library/aa355056.aspx&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;/div&gt;
</content><link rel='replies' type='application/atom+xml' href='http://dave-black.blogspot.com/feeds/1682972752280578456/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://dave-black.blogspot.com/2012/03/dont-use-using-with-wcf-proxy.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7674671342760410218/posts/default/1682972752280578456'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7674671342760410218/posts/default/1682972752280578456'/><link rel='alternate' type='text/html' href='http://dave-black.blogspot.com/2012/03/dont-use-using-with-wcf-proxy.html' title='Don&#39;t use &#39;using()&#39; with a WCF proxy'/><author><name>Dave Black</name><uri>http://www.blogger.com/profile/11787334586939943513</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEghXqyOIYI80jcRqlgdIPg99-1bldyR6NKQgYGs8Uq_88qc_HNUrHXqM0R_9FvephlqkYzrrmMwMjSs7JV9QVSQAZMlO5hinHcLQrYmcSTRbCS-g4JIfIJaOYteBSxEzGhnZd9T8HJI2sJ86vEVB-Y_6XqfYX3CkdriJnePd8Yrnav-bw/s1600/linked-in-profile-pic-1743640118751.jfif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7674671342760410218.post-6951189523335974985</id><published>2012-01-26T10:24:00.001-06:00</published><updated>2025-02-03T13:44:23.082-06:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="best practices"/><title type='text'>Why you should comment your code...</title><content type='html'>Here are the most important reasons for including comments/documentation when writing code:
&lt;ol&gt;

&lt;li&gt;I absolutely believe in documenting code using both XML doc comments on methods as well as unlined comments when/where necessary.  This facilitates docentation files being generated automatically and can be used to create .chm files.  For all of us who are lazy or those that think it takes too much time, use GhostDoc. Thus, laziness is no excuse.&lt;/li&gt;

&lt;li&gt;What if you have to maintain code that was written without comments?  Do you want to waste your time digging thru code?  What if it&#39;s more than just a method or class?  What if its a library or framework?  I personally have better things to do with my time.&lt;/li&gt;

&lt;li&gt;What about someone new to your team? What if your the new guy?  Is it easier to learn it with or without documentation/comments?&lt;/li&gt;

&lt;li&gt;If you are writing a framework, library or API that will be used by other teams/API consumers,  how are they supposed to know what it does without documentation?  Do you expect them to dig thru your code to figure it out?  What if they don&#39;t have access to the code?  Would you want to have to do this?&lt;/li&gt;

&lt;li&gt;What if you find some code without comments and the code looks wrong or inefficient?  It&#39;s certainly possible that it was written that way for a reason.  Only comments would help.&lt;/li&gt;

&lt;li&gt;In addition to adding comments, code itself should be self documenting: use descriptive class, member, variable, parameter and method  names.&lt;/li&gt;
&lt;/ol&gt;
When you write code, remember that you&#39;re not always going to be the one modifying, supporting it or consuming it...
&lt;br/&gt;&lt;br/&gt;
&lt;div&gt;
Peter Ritchie has a good post about what comments are NOT for - a pretty good read: &lt;a href=&quot;http://msmvps.com/blogs/peterritchie/archive/2012/01/30/what-code-comments-are-not-for.aspx&quot;&gt;http://msmvps.com/blogs/peterritchie/archive/2012/01/30/what-code-comments-are-not-for.aspx&lt;/a&gt;&lt;/div&gt;
&lt;br/&gt;&lt;br/&gt;</content><link rel='replies' type='application/atom+xml' href='http://dave-black.blogspot.com/feeds/6951189523335974985/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://dave-black.blogspot.com/2012/01/why-you-should-document-your-code.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7674671342760410218/posts/default/6951189523335974985'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7674671342760410218/posts/default/6951189523335974985'/><link rel='alternate' type='text/html' href='http://dave-black.blogspot.com/2012/01/why-you-should-document-your-code.html' title='Why you should comment your code...'/><author><name>Dave Black</name><uri>http://www.blogger.com/profile/11787334586939943513</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEghXqyOIYI80jcRqlgdIPg99-1bldyR6NKQgYGs8Uq_88qc_HNUrHXqM0R_9FvephlqkYzrrmMwMjSs7JV9QVSQAZMlO5hinHcLQrYmcSTRbCS-g4JIfIJaOYteBSxEzGhnZd9T8HJI2sJ86vEVB-Y_6XqfYX3CkdriJnePd8Yrnav-bw/s1600/linked-in-profile-pic-1743640118751.jfif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7674671342760410218.post-5208785432615337996</id><published>2011-12-08T12:09:00.003-06:00</published><updated>2025-02-03T13:44:38.113-06:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="compiled"/><category scheme="http://www.blogger.com/atom/ns#" term="debug"/><category scheme="http://www.blogger.com/atom/ns#" term="misc"/><category scheme="http://www.blogger.com/atom/ns#" term="pdb"/><category scheme="http://www.blogger.com/atom/ns#" term="release"/><title type='text'>How to Tell if an Assembly is Debug or Release</title><content type='html'>&lt;a href=&quot;http://www.codeproject.com/script/Articles/BlogFeedList.aspx?amid=3680616&quot; rel=&quot;tag&quot; style=&quot;display: none;&quot;&gt;CodeProject&lt;/a&gt;
The &lt;span style=&quot;color: #2b91af;&quot;&gt;DebuggableAttribute &lt;/span&gt;is present if you compile in any setting for &#39;Debug&#39; mode and when Release mode is selected and&amp;nbsp;Debug Info set&amp;nbsp;to anything other than &quot;none&quot;. So, just looking for the presence of &lt;span style=&quot;color: #2b91af;&quot;&gt;DebuggableAttribute &lt;/span&gt;is not sufficient and could be misleading. So, you could still have an assembly that is JIT optimized where the &lt;span style=&quot;color: #2b91af;&quot;&gt;DebuggableAttribute&lt;/span&gt; is present in the Assembly Manifest.&lt;br /&gt;
&lt;br /&gt;
First, you&amp;nbsp;need to define &lt;strong&gt;exactly&lt;/strong&gt; what is meant by &quot;Debug&quot; vs. &quot;Release&quot;...&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;Do you mean that the app is configured with code optimization?&lt;/li&gt;
&lt;li&gt;Do you mean that you can attach the VS/JIT Debugger to it?&lt;/li&gt;
&lt;li&gt;Do you mean that it generates DebugOutput?&lt;/li&gt;
&lt;li&gt;Do you mean that it defines the DEBUG constant?&amp;nbsp; Remember that you can conditionally compile Methods with the System.Diagnostics.Conditional() attribute.&lt;/li&gt;
&lt;/ul&gt;
IMHO, when someone asks whether or not an assembly is &quot;Debug&quot; or &quot;Release&quot;, they &lt;i&gt;really&lt;/i&gt; mean if the code is optimized...&lt;br /&gt;
&lt;br /&gt;
Sooo, do you want to do this manually or programmatically?&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;&lt;u&gt;Manually&lt;/u&gt;&lt;/b&gt;:&lt;br /&gt;
You need to view the value of the DebuggableAttribute bitmask for the assembly&#39;s metadata. &amp;nbsp;Here&#39;s how to do it:&lt;br /&gt;
&lt;br /&gt;
&lt;ol&gt;
&lt;li&gt;Open the assembly in ILDASM&lt;/li&gt;
&lt;li&gt;Open the Manifest&lt;/li&gt;
&lt;li&gt;Look at the DebuggableAttribute bitmask. &amp;nbsp;If the DebuggableAttribute is not present, it is definitely an Optimized assembly.&lt;/li&gt;
&lt;li&gt;If it is present, look at the 4th byte - if it is a &#39;0&#39; it is JIT Optimized - anything else, it is not:&lt;/li&gt;
&lt;/ol&gt;
// Metadata version: v4.0.30319&lt;br /&gt;
....&lt;br /&gt;
&lt;div&gt;
&lt;ol&gt;&lt;/ol&gt;
&amp;nbsp;// &amp;nbsp;.custom instance void [mscorlib]System.Diagnostics.DebuggableAttribute::.ctor(valuetype &lt;b&gt;[mscorlib]System.Diagnostics.DebuggableAttribute/DebuggingModes) = ( 01 00 02 &lt;span style=&quot;background-color: yellow;&quot;&gt;00&lt;/span&gt; 00 00 00 00 )&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;&lt;u&gt;Programmatically&lt;/u&gt;&lt;/b&gt;: assuming that you want to know programmatically if the code is JITOptimized, here is the correct implementation:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;
&lt;pre style=&quot;font-family:Consolas;font-size:13px;color:#dadada;background:#1e1e1e;&quot;&gt;&lt;span style=&quot;color:#569cd6;&quot;&gt;void&lt;/span&gt;&amp;nbsp;&lt;span style=&quot;color:#dcdcaa;&quot;&gt;Main&lt;/span&gt;&lt;span style=&quot;color:gainsboro;&quot;&gt;()&lt;/span&gt;
&lt;span style=&quot;color:gainsboro;&quot;&gt;{&lt;/span&gt;
	&lt;span style=&quot;color:#569cd6;&quot;&gt;var&lt;/span&gt;&amp;nbsp;&lt;span style=&quot;color:#9cdcfe;&quot;&gt;HasDebuggableAttribute&lt;/span&gt;&amp;nbsp;&lt;span style=&quot;color:#b4b4b4;&quot;&gt;=&lt;/span&gt;&amp;nbsp;&lt;span style=&quot;color:#569cd6;&quot;&gt;false&lt;/span&gt;&lt;span style=&quot;color:gainsboro;&quot;&gt;;&lt;/span&gt;
	&lt;span style=&quot;color:#569cd6;&quot;&gt;var&lt;/span&gt;&amp;nbsp;&lt;span style=&quot;color:#9cdcfe;&quot;&gt;IsJITOptimized&lt;/span&gt;&amp;nbsp;&lt;span style=&quot;color:#b4b4b4;&quot;&gt;=&lt;/span&gt;&amp;nbsp;&lt;span style=&quot;color:#569cd6;&quot;&gt;false&lt;/span&gt;&lt;span style=&quot;color:gainsboro;&quot;&gt;;&lt;/span&gt;
	&lt;span style=&quot;color:#569cd6;&quot;&gt;var&lt;/span&gt;&amp;nbsp;&lt;span style=&quot;color:#9cdcfe;&quot;&gt;IsJITTrackingEnabled&lt;/span&gt;&amp;nbsp;&lt;span style=&quot;color:#b4b4b4;&quot;&gt;=&lt;/span&gt;&amp;nbsp;&lt;span style=&quot;color:#569cd6;&quot;&gt;false&lt;/span&gt;&lt;span style=&quot;color:gainsboro;&quot;&gt;;&lt;/span&gt;
	&lt;span style=&quot;color:#569cd6;&quot;&gt;var&lt;/span&gt;&amp;nbsp;&lt;span style=&quot;color:#9cdcfe;&quot;&gt;BuildType&lt;/span&gt;&amp;nbsp;&lt;span style=&quot;color:#b4b4b4;&quot;&gt;=&lt;/span&gt;&amp;nbsp;&lt;span style=&quot;color:#d69d85;&quot;&gt;&amp;quot;&amp;quot;&lt;/span&gt;&lt;span style=&quot;color:gainsboro;&quot;&gt;;&lt;/span&gt;
	&lt;span style=&quot;color:#569cd6;&quot;&gt;var&lt;/span&gt;&amp;nbsp;&lt;span style=&quot;color:#9cdcfe;&quot;&gt;DebugOutput&lt;/span&gt;&amp;nbsp;&lt;span style=&quot;color:#b4b4b4;&quot;&gt;=&lt;/span&gt;&amp;nbsp;&lt;span style=&quot;color:#d69d85;&quot;&gt;&amp;quot;&amp;quot;&lt;/span&gt;&lt;span style=&quot;color:gainsboro;&quot;&gt;;&lt;/span&gt;
	&lt;span style=&quot;color:#569cd6;&quot;&gt;var&lt;/span&gt;&amp;nbsp;&lt;span style=&quot;color:#9cdcfe;&quot;&gt;ReflectedAssembly&lt;/span&gt;&amp;nbsp;&lt;span style=&quot;color:#b4b4b4;&quot;&gt;=&lt;/span&gt;&amp;nbsp;&lt;span style=&quot;color:gainsboro;&quot;&gt;Assembly&lt;/span&gt;&lt;span style=&quot;color:#b4b4b4;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:gainsboro;&quot;&gt;LoadFile&lt;/span&gt;&lt;span style=&quot;color:gainsboro;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#d69d85;&quot;&gt;@&amp;quot;C:\src\TMDE\Git\RedisScalingTest\bin\Release\netcoreapp3.1\RedisScalingTest.dll&amp;quot;&lt;/span&gt;&lt;span style=&quot;color:gainsboro;&quot;&gt;);&lt;/span&gt;
 
	&lt;span style=&quot;color:#57a64a;&quot;&gt;//	var&amp;nbsp;ReflectedAssembly&amp;nbsp;=&amp;nbsp;Assembly.LoadFile(@&amp;quot;path&amp;nbsp;to&amp;nbsp;the&amp;nbsp;dll&amp;nbsp;you&amp;nbsp;are&amp;nbsp;testing&amp;quot;);&lt;/span&gt;
	&lt;span style=&quot;color:#569cd6;&quot;&gt;object&lt;/span&gt;&lt;span style=&quot;color:gainsboro;&quot;&gt;[]&lt;/span&gt;&amp;nbsp;&lt;span style=&quot;color:#9cdcfe;&quot;&gt;attribs&lt;/span&gt;&amp;nbsp;&lt;span style=&quot;color:#b4b4b4;&quot;&gt;=&lt;/span&gt;&amp;nbsp;&lt;span style=&quot;color:#9cdcfe;&quot;&gt;ReflectedAssembly&lt;/span&gt;&lt;span style=&quot;color:#b4b4b4;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:gainsboro;&quot;&gt;GetCustomAttributes&lt;/span&gt;&lt;span style=&quot;color:gainsboro;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#569cd6;&quot;&gt;typeof&lt;/span&gt;&lt;span style=&quot;color:gainsboro;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:gainsboro;&quot;&gt;DebuggableAttribute&lt;/span&gt;&lt;span style=&quot;color:gainsboro;&quot;&gt;),&lt;/span&gt;&amp;nbsp;&lt;span style=&quot;color:#569cd6;&quot;&gt;false&lt;/span&gt;&lt;span style=&quot;color:gainsboro;&quot;&gt;);&lt;/span&gt;
 
	&lt;span style=&quot;color:#57a64a;&quot;&gt;//&amp;nbsp;If&amp;nbsp;the&amp;nbsp;&amp;#39;DebuggableAttribute&amp;#39;&amp;nbsp;is&amp;nbsp;not&amp;nbsp;found&amp;nbsp;then&amp;nbsp;it&amp;nbsp;is&amp;nbsp;definitely&amp;nbsp;an&amp;nbsp;OPTIMIZED&amp;nbsp;build&lt;/span&gt;
	&lt;span style=&quot;color:#d8a0df;&quot;&gt;if&lt;/span&gt;&amp;nbsp;&lt;span style=&quot;color:gainsboro;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9cdcfe;&quot;&gt;attribs&lt;/span&gt;&lt;span style=&quot;color:#b4b4b4;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:gainsboro;&quot;&gt;Length&lt;/span&gt;&amp;nbsp;&lt;span style=&quot;color:#b4b4b4;&quot;&gt;&amp;gt;&lt;/span&gt;&amp;nbsp;&lt;span style=&quot;color:#b5cea8;&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color:gainsboro;&quot;&gt;)&lt;/span&gt;
	&lt;span style=&quot;color:gainsboro;&quot;&gt;{&lt;/span&gt;
		&lt;span style=&quot;color:#57a64a;&quot;&gt;//&amp;nbsp;Just&amp;nbsp;because&amp;nbsp;the&amp;nbsp;&amp;#39;DebuggableAttribute&amp;#39;&amp;nbsp;is&amp;nbsp;found&amp;nbsp;doesn&amp;#39;t&amp;nbsp;necessarily&amp;nbsp;mean&lt;/span&gt;
		&lt;span style=&quot;color:#57a64a;&quot;&gt;//&amp;nbsp;it&amp;#39;s&amp;nbsp;a&amp;nbsp;DEBUG&amp;nbsp;build;&amp;nbsp;we&amp;nbsp;have&amp;nbsp;to&amp;nbsp;check&amp;nbsp;the&amp;nbsp;JIT&amp;nbsp;Optimization&amp;nbsp;flag&lt;/span&gt;
		&lt;span style=&quot;color:#57a64a;&quot;&gt;//&amp;nbsp;i.e.&amp;nbsp;it&amp;nbsp;could&amp;nbsp;have&amp;nbsp;the&amp;nbsp;&amp;quot;generate&amp;nbsp;PDB&amp;quot;&amp;nbsp;checked&amp;nbsp;but&amp;nbsp;have&amp;nbsp;JIT&amp;nbsp;Optimization&amp;nbsp;enabled&lt;/span&gt;
		&lt;span style=&quot;color:gainsboro;&quot;&gt;DebuggableAttribute&lt;/span&gt;&amp;nbsp;&lt;span style=&quot;color:#9cdcfe;&quot;&gt;debuggableAttribute&lt;/span&gt;&amp;nbsp;&lt;span style=&quot;color:#b4b4b4;&quot;&gt;=&lt;/span&gt;&amp;nbsp;&lt;span style=&quot;color:#9cdcfe;&quot;&gt;attribs&lt;/span&gt;&lt;span style=&quot;color:gainsboro;&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color:#b5cea8;&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color:gainsboro;&quot;&gt;]&lt;/span&gt;&amp;nbsp;&lt;span style=&quot;color:#569cd6;&quot;&gt;as&lt;/span&gt;&amp;nbsp;&lt;span style=&quot;color:gainsboro;&quot;&gt;DebuggableAttribute&lt;/span&gt;&lt;span style=&quot;color:gainsboro;&quot;&gt;;&lt;/span&gt;
		&lt;span style=&quot;color:#d8a0df;&quot;&gt;if&lt;/span&gt;&amp;nbsp;&lt;span style=&quot;color:gainsboro;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9cdcfe;&quot;&gt;debuggableAttribute&lt;/span&gt;&amp;nbsp;&lt;span style=&quot;color:#b4b4b4;&quot;&gt;!=&lt;/span&gt;&amp;nbsp;&lt;span style=&quot;color:#569cd6;&quot;&gt;null&lt;/span&gt;&lt;span style=&quot;color:gainsboro;&quot;&gt;)&lt;/span&gt;
		&lt;span style=&quot;color:gainsboro;&quot;&gt;{&lt;/span&gt;
			&lt;span style=&quot;color:#9cdcfe;&quot;&gt;HasDebuggableAttribute&lt;/span&gt;&amp;nbsp;&lt;span style=&quot;color:#b4b4b4;&quot;&gt;=&lt;/span&gt;&amp;nbsp;&lt;span style=&quot;color:#569cd6;&quot;&gt;true&lt;/span&gt;&lt;span style=&quot;color:gainsboro;&quot;&gt;;&lt;/span&gt;
			&lt;span style=&quot;color:#9cdcfe;&quot;&gt;IsJITOptimized&lt;/span&gt;&amp;nbsp;&lt;span style=&quot;color:#b4b4b4;&quot;&gt;=&lt;/span&gt;&amp;nbsp;&lt;span style=&quot;color:#b4b4b4;&quot;&gt;!&lt;/span&gt;&lt;span style=&quot;color:#9cdcfe;&quot;&gt;debuggableAttribute&lt;/span&gt;&lt;span style=&quot;color:#b4b4b4;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:gainsboro;&quot;&gt;IsJITOptimizerDisabled&lt;/span&gt;&lt;span style=&quot;color:gainsboro;&quot;&gt;;&lt;/span&gt;
 
			&lt;span style=&quot;color:#57a64a;&quot;&gt;//&amp;nbsp;IsJITTrackingEnabled&amp;nbsp;-&amp;nbsp;Gets&amp;nbsp;a&amp;nbsp;value&amp;nbsp;that&amp;nbsp;indicates&amp;nbsp;whether&amp;nbsp;the&amp;nbsp;runtime&amp;nbsp;will&amp;nbsp;track&amp;nbsp;information&amp;nbsp;during&amp;nbsp;code&amp;nbsp;generation&amp;nbsp;for&amp;nbsp;the&amp;nbsp;debugger.&lt;/span&gt;
			&lt;span style=&quot;color:#9cdcfe;&quot;&gt;IsJITTrackingEnabled&lt;/span&gt;&amp;nbsp;&lt;span style=&quot;color:#b4b4b4;&quot;&gt;=&lt;/span&gt;&amp;nbsp;&lt;span style=&quot;color:#9cdcfe;&quot;&gt;debuggableAttribute&lt;/span&gt;&lt;span style=&quot;color:#b4b4b4;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:gainsboro;&quot;&gt;IsJITTrackingEnabled&lt;/span&gt;&lt;span style=&quot;color:gainsboro;&quot;&gt;;&lt;/span&gt;
			&lt;span style=&quot;color:#9cdcfe;&quot;&gt;BuildType&lt;/span&gt;&amp;nbsp;&lt;span style=&quot;color:#b4b4b4;&quot;&gt;=&lt;/span&gt;&amp;nbsp;&lt;span style=&quot;color:#9cdcfe;&quot;&gt;debuggableAttribute&lt;/span&gt;&lt;span style=&quot;color:#b4b4b4;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:gainsboro;&quot;&gt;IsJITOptimizerDisabled&lt;/span&gt;&amp;nbsp;&lt;span style=&quot;color:#b4b4b4;&quot;&gt;?&lt;/span&gt;&amp;nbsp;&lt;span style=&quot;color:#d69d85;&quot;&gt;&amp;quot;Debug&amp;quot;&lt;/span&gt;&amp;nbsp;&lt;span style=&quot;color:#b4b4b4;&quot;&gt;:&lt;/span&gt;&amp;nbsp;&lt;span style=&quot;color:#d69d85;&quot;&gt;&amp;quot;Release&amp;quot;&lt;/span&gt;&lt;span style=&quot;color:gainsboro;&quot;&gt;;&lt;/span&gt;
 
			&lt;span style=&quot;color:#57a64a;&quot;&gt;//&amp;nbsp;check&amp;nbsp;for&amp;nbsp;Debug&amp;nbsp;Output&amp;nbsp;&amp;quot;full&amp;quot;&amp;nbsp;or&amp;nbsp;&amp;quot;pdb-only&amp;quot;&lt;/span&gt;
			&lt;span style=&quot;color:#9cdcfe;&quot;&gt;DebugOutput&lt;/span&gt;&amp;nbsp;&lt;span style=&quot;color:#b4b4b4;&quot;&gt;=&lt;/span&gt;&amp;nbsp;&lt;span style=&quot;color:gainsboro;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9cdcfe;&quot;&gt;debuggableAttribute&lt;/span&gt;&lt;span style=&quot;color:#b4b4b4;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:gainsboro;&quot;&gt;DebuggingFlags&lt;/span&gt;&amp;nbsp;&lt;span style=&quot;color:#b4b4b4;&quot;&gt;&amp;amp;&lt;/span&gt;
							&lt;span style=&quot;color:gainsboro;&quot;&gt;DebuggableAttribute&lt;/span&gt;&lt;span style=&quot;color:#b4b4b4;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:gainsboro;&quot;&gt;DebuggingModes&lt;/span&gt;&lt;span style=&quot;color:#b4b4b4;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:gainsboro;&quot;&gt;Default&lt;/span&gt;&lt;span style=&quot;color:gainsboro;&quot;&gt;)&lt;/span&gt;&amp;nbsp;&lt;span style=&quot;color:#b4b4b4;&quot;&gt;!=&lt;/span&gt;
							&lt;span style=&quot;color:gainsboro;&quot;&gt;DebuggableAttribute&lt;/span&gt;&lt;span style=&quot;color:#b4b4b4;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:gainsboro;&quot;&gt;DebuggingModes&lt;/span&gt;&lt;span style=&quot;color:#b4b4b4;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:gainsboro;&quot;&gt;None&lt;/span&gt;
							&lt;span style=&quot;color:#b4b4b4;&quot;&gt;?&lt;/span&gt;&amp;nbsp;&lt;span style=&quot;color:#d69d85;&quot;&gt;&amp;quot;Full&amp;quot;&lt;/span&gt;&amp;nbsp;&lt;span style=&quot;color:#b4b4b4;&quot;&gt;:&lt;/span&gt;&amp;nbsp;&lt;span style=&quot;color:#d69d85;&quot;&gt;&amp;quot;pdb-only&amp;quot;&lt;/span&gt;&lt;span style=&quot;color:gainsboro;&quot;&gt;;&lt;/span&gt;
		&lt;span style=&quot;color:gainsboro;&quot;&gt;}&lt;/span&gt;
	&lt;span style=&quot;color:gainsboro;&quot;&gt;}&lt;/span&gt;
	&lt;span style=&quot;color:#d8a0df;&quot;&gt;else&lt;/span&gt;
	&lt;span style=&quot;color:gainsboro;&quot;&gt;{&lt;/span&gt;
		&lt;span style=&quot;color:#9cdcfe;&quot;&gt;IsJITOptimized&lt;/span&gt;&amp;nbsp;&lt;span style=&quot;color:#b4b4b4;&quot;&gt;=&lt;/span&gt;&amp;nbsp;&lt;span style=&quot;color:#569cd6;&quot;&gt;true&lt;/span&gt;&lt;span style=&quot;color:gainsboro;&quot;&gt;;&lt;/span&gt;
		&lt;span style=&quot;color:#9cdcfe;&quot;&gt;BuildType&lt;/span&gt;&amp;nbsp;&lt;span style=&quot;color:#b4b4b4;&quot;&gt;=&lt;/span&gt;&amp;nbsp;&lt;span style=&quot;color:#d69d85;&quot;&gt;&amp;quot;Release&amp;quot;&lt;/span&gt;&lt;span style=&quot;color:gainsboro;&quot;&gt;;&lt;/span&gt;
	&lt;span style=&quot;color:gainsboro;&quot;&gt;}&lt;/span&gt;
 
	&lt;span style=&quot;color:#4ec9b0;&quot;&gt;Console&lt;/span&gt;&lt;span style=&quot;color:#b4b4b4;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#dcdcaa;&quot;&gt;WriteLine&lt;/span&gt;&lt;span style=&quot;color:gainsboro;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#d69d85;&quot;&gt;$&amp;quot;&lt;/span&gt;&lt;span style=&quot;color:gainsboro;&quot;&gt;{&lt;/span&gt;&lt;span style=&quot;color:#569cd6;&quot;&gt;nameof&lt;/span&gt;&lt;span style=&quot;color:gainsboro;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9cdcfe;&quot;&gt;HasDebuggableAttribute&lt;/span&gt;&lt;span style=&quot;color:gainsboro;&quot;&gt;)}&lt;/span&gt;&lt;span style=&quot;color:#d69d85;&quot;&gt;:&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color:gainsboro;&quot;&gt;{&lt;/span&gt;&lt;span style=&quot;color:#9cdcfe;&quot;&gt;HasDebuggableAttribute&lt;/span&gt;&lt;span style=&quot;color:gainsboro;&quot;&gt;}&lt;/span&gt;&lt;span style=&quot;color:#d69d85;&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span style=&quot;color:gainsboro;&quot;&gt;);&lt;/span&gt;
	&lt;span style=&quot;color:#4ec9b0;&quot;&gt;Console&lt;/span&gt;&lt;span style=&quot;color:#b4b4b4;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#dcdcaa;&quot;&gt;WriteLine&lt;/span&gt;&lt;span style=&quot;color:gainsboro;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#d69d85;&quot;&gt;$&amp;quot;&lt;/span&gt;&lt;span style=&quot;color:gainsboro;&quot;&gt;{&lt;/span&gt;&lt;span style=&quot;color:#569cd6;&quot;&gt;nameof&lt;/span&gt;&lt;span style=&quot;color:gainsboro;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9cdcfe;&quot;&gt;IsJITOptimized&lt;/span&gt;&lt;span style=&quot;color:gainsboro;&quot;&gt;)}&lt;/span&gt;&lt;span style=&quot;color:#d69d85;&quot;&gt;:&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color:gainsboro;&quot;&gt;{&lt;/span&gt;&lt;span style=&quot;color:#9cdcfe;&quot;&gt;IsJITOptimized&lt;/span&gt;&lt;span style=&quot;color:gainsboro;&quot;&gt;}&lt;/span&gt;&lt;span style=&quot;color:#d69d85;&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span style=&quot;color:gainsboro;&quot;&gt;);&lt;/span&gt;
	&lt;span style=&quot;color:#4ec9b0;&quot;&gt;Console&lt;/span&gt;&lt;span style=&quot;color:#b4b4b4;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#dcdcaa;&quot;&gt;WriteLine&lt;/span&gt;&lt;span style=&quot;color:gainsboro;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#d69d85;&quot;&gt;$&amp;quot;&lt;/span&gt;&lt;span style=&quot;color:gainsboro;&quot;&gt;{&lt;/span&gt;&lt;span style=&quot;color:#569cd6;&quot;&gt;nameof&lt;/span&gt;&lt;span style=&quot;color:gainsboro;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9cdcfe;&quot;&gt;IsJITTrackingEnabled&lt;/span&gt;&lt;span style=&quot;color:gainsboro;&quot;&gt;)}&lt;/span&gt;&lt;span style=&quot;color:#d69d85;&quot;&gt;:&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color:gainsboro;&quot;&gt;{&lt;/span&gt;&lt;span style=&quot;color:#9cdcfe;&quot;&gt;IsJITTrackingEnabled&lt;/span&gt;&lt;span style=&quot;color:gainsboro;&quot;&gt;}&lt;/span&gt;&lt;span style=&quot;color:#d69d85;&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span style=&quot;color:gainsboro;&quot;&gt;);&lt;/span&gt;
	&lt;span style=&quot;color:#4ec9b0;&quot;&gt;Console&lt;/span&gt;&lt;span style=&quot;color:#b4b4b4;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#dcdcaa;&quot;&gt;WriteLine&lt;/span&gt;&lt;span style=&quot;color:gainsboro;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#d69d85;&quot;&gt;$&amp;quot;&lt;/span&gt;&lt;span style=&quot;color:gainsboro;&quot;&gt;{&lt;/span&gt;&lt;span style=&quot;color:#569cd6;&quot;&gt;nameof&lt;/span&gt;&lt;span style=&quot;color:gainsboro;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9cdcfe;&quot;&gt;BuildType&lt;/span&gt;&lt;span style=&quot;color:gainsboro;&quot;&gt;)}&lt;/span&gt;&lt;span style=&quot;color:#d69d85;&quot;&gt;:&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color:gainsboro;&quot;&gt;{&lt;/span&gt;&lt;span style=&quot;color:#9cdcfe;&quot;&gt;BuildType&lt;/span&gt;&lt;span style=&quot;color:gainsboro;&quot;&gt;}&lt;/span&gt;&lt;span style=&quot;color:#d69d85;&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span style=&quot;color:gainsboro;&quot;&gt;);&lt;/span&gt;
	&lt;span style=&quot;color:#4ec9b0;&quot;&gt;Console&lt;/span&gt;&lt;span style=&quot;color:#b4b4b4;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#dcdcaa;&quot;&gt;WriteLine&lt;/span&gt;&lt;span style=&quot;color:gainsboro;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#d69d85;&quot;&gt;$&amp;quot;&lt;/span&gt;&lt;span style=&quot;color:gainsboro;&quot;&gt;{&lt;/span&gt;&lt;span style=&quot;color:#569cd6;&quot;&gt;nameof&lt;/span&gt;&lt;span style=&quot;color:gainsboro;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9cdcfe;&quot;&gt;DebugOutput&lt;/span&gt;&lt;span style=&quot;color:gainsboro;&quot;&gt;)}&lt;/span&gt;&lt;span style=&quot;color:#d69d85;&quot;&gt;:&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color:gainsboro;&quot;&gt;{&lt;/span&gt;&lt;span style=&quot;color:#9cdcfe;&quot;&gt;DebugOutput&lt;/span&gt;&lt;span style=&quot;color:gainsboro;&quot;&gt;}&lt;/span&gt;&lt;span style=&quot;color:#d69d85;&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span style=&quot;color:gainsboro;&quot;&gt;);&lt;/span&gt;
&lt;span style=&quot;color:gainsboro;&quot;&gt;}&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;&lt;/div&gt;
</content><link rel='replies' type='application/atom+xml' href='http://dave-black.blogspot.com/feeds/5208785432615337996/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://dave-black.blogspot.com/2011/12/how-to-tell-if-assembly-is-debug-or.html#comment-form' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7674671342760410218/posts/default/5208785432615337996'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7674671342760410218/posts/default/5208785432615337996'/><link rel='alternate' type='text/html' href='http://dave-black.blogspot.com/2011/12/how-to-tell-if-assembly-is-debug-or.html' title='How to Tell if an Assembly is Debug or Release'/><author><name>Dave Black</name><uri>http://www.blogger.com/profile/11787334586939943513</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEghXqyOIYI80jcRqlgdIPg99-1bldyR6NKQgYGs8Uq_88qc_HNUrHXqM0R_9FvephlqkYzrrmMwMjSs7JV9QVSQAZMlO5hinHcLQrYmcSTRbCS-g4JIfIJaOYteBSxEzGhnZd9T8HJI2sJ86vEVB-Y_6XqfYX3CkdriJnePd8Yrnav-bw/s1600/linked-in-profile-pic-1743640118751.jfif'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7674671342760410218.post-406043378235051515</id><published>2011-07-29T13:38:00.003-05:00</published><updated>2011-08-11T00:37:54.501-05:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="misc"/><title type='text'>My Favorite Quotes</title><content type='html'>Here are some of my favorite quotes:&lt;br /&gt;
&lt;br /&gt;
&quot;Debugging is twice as hard as writing code in the first place.&amp;nbsp; Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it.&quot;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; - Brian Kernighan&lt;br /&gt;
&lt;br /&gt;
&quot;Intellectuals solve problems; geniuses prevent them.&quot;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; - Albert Einstein&lt;br /&gt;
&lt;br /&gt;
&quot;There are three categories of open issues with our application: those that we know about, those that we don&#39;t know about, and those that we don&#39;t know that we don&#39;t know about.&quot;&amp;nbsp; Someone in the group actually asked &quot;Can you give an example of the last one?&quot;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; - former coworker&lt;br /&gt;
&lt;br /&gt;
&quot;It&#39;s not a bug, it&#39;s a feature&quot;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; - unknown&lt;br /&gt;
&lt;br /&gt;
&quot;Bugs are a form of job security.&quot;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; - unknown&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: inherit;&quot;&gt;&quot;If debugging is the process of removing bugs, then programming must be the process of putting them in.&quot;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: inherit;&quot;&gt;&amp;nbsp; - Edsger Dijkstra&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: inherit;&quot;&gt;&lt;/span&gt;&lt;span style=&quot;font-family: inherit;&quot;&gt;&quot;The only difference between a beginning programmer and an experienced one is the complexity of the bugs they write.&quot;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: inherit;&quot;&gt;&amp;nbsp; - Dave Black&lt;/span&gt;&lt;br /&gt;
</content><link rel='replies' type='application/atom+xml' href='http://dave-black.blogspot.com/feeds/406043378235051515/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://dave-black.blogspot.com/2011/07/my-favorite-quotes.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7674671342760410218/posts/default/406043378235051515'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7674671342760410218/posts/default/406043378235051515'/><link rel='alternate' type='text/html' href='http://dave-black.blogspot.com/2011/07/my-favorite-quotes.html' title='My Favorite Quotes'/><author><name>Dave Black</name><uri>http://www.blogger.com/profile/11787334586939943513</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEghXqyOIYI80jcRqlgdIPg99-1bldyR6NKQgYGs8Uq_88qc_HNUrHXqM0R_9FvephlqkYzrrmMwMjSs7JV9QVSQAZMlO5hinHcLQrYmcSTRbCS-g4JIfIJaOYteBSxEzGhnZd9T8HJI2sJ86vEVB-Y_6XqfYX3CkdriJnePd8Yrnav-bw/s1600/linked-in-profile-pic-1743640118751.jfif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7674671342760410218.post-4909488817189801097</id><published>2011-06-06T12:36:00.000-05:00</published><updated>2011-06-06T12:36:53.882-05:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="tools"/><title type='text'>Finally a good free multi-monitor tool</title><content type='html'>&lt;a href=&quot;http://www.timstall.com/2011/05/tool-winsplit-revolution-move-windows.html?spref=bl&quot;&gt;timstall: Tool - WinSplit Revolution - move windows between ...&lt;/a&gt;: &quot;A coworker showed me a useful (and free!) tool that conveniently positions open windows on your screen.   The tool is Winsplit Revolution , ...&quot;</content><link rel='replies' type='application/atom+xml' href='http://dave-black.blogspot.com/feeds/4909488817189801097/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://dave-black.blogspot.com/2011/06/finally-good-free-multi-monitor-tool.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7674671342760410218/posts/default/4909488817189801097'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7674671342760410218/posts/default/4909488817189801097'/><link rel='alternate' type='text/html' href='http://dave-black.blogspot.com/2011/06/finally-good-free-multi-monitor-tool.html' title='Finally a good free multi-monitor tool'/><author><name>Dave Black</name><uri>http://www.blogger.com/profile/11787334586939943513</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEghXqyOIYI80jcRqlgdIPg99-1bldyR6NKQgYGs8Uq_88qc_HNUrHXqM0R_9FvephlqkYzrrmMwMjSs7JV9QVSQAZMlO5hinHcLQrYmcSTRbCS-g4JIfIJaOYteBSxEzGhnZd9T8HJI2sJ86vEVB-Y_6XqfYX3CkdriJnePd8Yrnav-bw/s1600/linked-in-profile-pic-1743640118751.jfif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7674671342760410218.post-2073912444978137935</id><published>2011-04-29T13:49:00.001-05:00</published><updated>2025-02-03T13:49:37.749-06:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="debugging"/><category scheme="http://www.blogger.com/atom/ns#" term="tools"/><category scheme="http://www.blogger.com/atom/ns#" term="windbg"/><title type='text'>New WinDbg Extension available</title><content type='html'>I&#39;m happy to announce that a new version of the WinDbg debugging extension PSSCOR2 (now called PSSCOR4) has been released.&amp;nbsp; It is available for public download here:&amp;nbsp; &lt;br /&gt;
&lt;br /&gt;
&lt;a href=&quot;http://www.microsoft.com/downloads/en/details.aspx?FamilyID=a06a0fea-a4d4-434e-a527-d6afa2e552dd&quot;&gt;http://www.microsoft.com/downloads/en/details.aspx?FamilyID=a06a0fea-a4d4-434e-a527-d6afa2e552dd&lt;/a&gt;</content><link rel='replies' type='application/atom+xml' href='http://dave-black.blogspot.com/feeds/2073912444978137935/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://dave-black.blogspot.com/2011/04/new-windbg-extension-available.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7674671342760410218/posts/default/2073912444978137935'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7674671342760410218/posts/default/2073912444978137935'/><link rel='alternate' type='text/html' href='http://dave-black.blogspot.com/2011/04/new-windbg-extension-available.html' title='New WinDbg Extension available'/><author><name>Dave Black</name><uri>http://www.blogger.com/profile/11787334586939943513</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEghXqyOIYI80jcRqlgdIPg99-1bldyR6NKQgYGs8Uq_88qc_HNUrHXqM0R_9FvephlqkYzrrmMwMjSs7JV9QVSQAZMlO5hinHcLQrYmcSTRbCS-g4JIfIJaOYteBSxEzGhnZd9T8HJI2sJ86vEVB-Y_6XqfYX3CkdriJnePd8Yrnav-bw/s1600/linked-in-profile-pic-1743640118751.jfif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7674671342760410218.post-4728701254950880022</id><published>2011-04-28T08:00:00.002-05:00</published><updated>2025-02-03T13:49:25.925-06:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="debugging"/><category scheme="http://www.blogger.com/atom/ns#" term="tools"/><title type='text'>Whitepaper on the Debug Diagnostic Tool v1.1 - IIS debugging and debugdiag - Site Home - MSDN Blogs</title><content type='html'>&lt;a href=&quot;http://blogs.msdn.com/b/lagdas/archive/2009/04/30/whitepaper-on-the-debug-diagnostic-tool-v1-1.aspx&quot;&gt;Whitepaper on the Debug Diagnostic Tool v1.1 - IIS debugging and debugdiag - Site Home - MSDN Blogs&lt;/a&gt;</content><link rel='replies' type='application/atom+xml' href='http://dave-black.blogspot.com/feeds/4728701254950880022/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://dave-black.blogspot.com/2011/04/whitepaper-on-debug-diagnostic-tool-v11.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7674671342760410218/posts/default/4728701254950880022'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7674671342760410218/posts/default/4728701254950880022'/><link rel='alternate' type='text/html' href='http://dave-black.blogspot.com/2011/04/whitepaper-on-debug-diagnostic-tool-v11.html' title='Whitepaper on the Debug Diagnostic Tool v1.1 - IIS debugging and debugdiag - Site Home - MSDN Blogs'/><author><name>Dave Black</name><uri>http://www.blogger.com/profile/11787334586939943513</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEghXqyOIYI80jcRqlgdIPg99-1bldyR6NKQgYGs8Uq_88qc_HNUrHXqM0R_9FvephlqkYzrrmMwMjSs7JV9QVSQAZMlO5hinHcLQrYmcSTRbCS-g4JIfIJaOYteBSxEzGhnZd9T8HJI2sJ86vEVB-Y_6XqfYX3CkdriJnePd8Yrnav-bw/s1600/linked-in-profile-pic-1743640118751.jfif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7674671342760410218.post-5798599954425766857</id><published>2011-03-09T16:57:00.001-06:00</published><updated>2025-02-03T13:48:25.679-06:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="IIS"/><category scheme="http://www.blogger.com/atom/ns#" term="tools"/><title type='text'>IIS Tools that you should have...</title><content type='html'>&lt;div class=&quot;MsoNormal&quot; style=&quot;margin: 0in 0in 0pt;&quot;&gt;Here is a list of IIS tools I&#39;ve used in the past and their respective links.&amp;nbsp; Please note that all of these tools are FREE and widely used in the industry.&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;margin: 0in 0in 0pt;&quot;&gt;&amp;nbsp;&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;margin: 0in 0in 0pt;&quot;&gt;&lt;strong&gt;IIS Web Deploy 2.0&lt;/strong&gt;&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;margin: 0in 0in 0pt;&quot;&gt;&lt;a href=&quot;http://www.iis.net/download/WebDeploy&quot;&gt;http://www.iis.net/download/WebDeploy&lt;/a&gt;&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;margin: 0in 0in 0pt;&quot;&gt;&amp;nbsp;&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;margin: 0in 0in 0pt;&quot;&gt;&amp;nbsp;&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;margin: 0in 0in 0pt;&quot;&gt;&lt;strong&gt;IIS 6.0 Resource Kit&lt;/strong&gt; (many tools included here – most helpful are probably IIS 6.0 Migration Tool and the IIS Metabase Explorer)&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;margin: 0in 0in 0pt;&quot;&gt;&lt;a href=&quot;http://www.microsoft.com/downloads/en/details.aspx?FamilyID=56fc92ee-a71a-4c73-b628-ade629c89499&amp;amp;displaylang=en&quot;&gt;http://www.microsoft.com/downloads/en/details.aspx?FamilyID=56fc92ee-a71a-4c73-b628-ade629c89499&amp;amp;displaylang=en&lt;/a&gt;&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;margin: 0in 0in 0pt;&quot;&gt;&amp;nbsp;&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;margin: 0in 0in 0pt;&quot;&gt;&amp;nbsp;&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;margin: 0in 0in 0pt;&quot;&gt;&lt;strong&gt;IIS Diagnostics Kit – IIS Diag&lt;/strong&gt;&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;margin: 0in 0in 0pt;&quot;&gt;&lt;a href=&quot;http://www.microsoft.com/downloads/en/details.aspx?FamilyID=9bfa49bc-376b-4a54-95aa-73c9156706e7&quot;&gt;http://www.microsoft.com/downloads/en/details.aspx?FamilyID=9bfa49bc-376b-4a54-95aa-73c9156706e7&lt;/a&gt;&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;margin: 0in 0in 0pt;&quot;&gt;&amp;nbsp;&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;margin: 0in 0in 0pt;&quot;&gt;This includes a number of tools which help diagnose various types of problems with IIS setup and configuration:&lt;/div&gt;&lt;ul&gt;&lt;li&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;margin: 0in 0in 0pt;&quot;&gt;AuthDiag - authentication and ACL problems&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;margin: 0in 0in 0pt;&quot;&gt;SSL Diag - SSL-related problems&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;margin: 0in 0in 0pt;&quot;&gt;SMTP Diag - smtp-related issues&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;margin: 0in 0in 0pt;&quot;&gt;Log Parser - allows for easy reading of IIS log files&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;margin: 0in 0in 0pt;&quot;&gt;Debug Diag - allows you to create memory dumps manually or automatically when IIS hangs.&amp;nbsp; It also&amp;nbsp;can run a memory ananlysis from the memory dump captured!&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;margin: 0in 0in 0pt;&quot;&gt;and others...&lt;/div&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;margin: 0in 0in 0pt;&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;margin: 0in 0in 0pt;&quot;&gt;&lt;strong&gt;Event Log Explorer&lt;/strong&gt; -&amp;nbsp;allows you to create custom queries and filters against anything in the Event Viewer – very cool!&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;margin: 0in 0in 0pt;&quot;&gt;&lt;a href=&quot;http://www.eventlogxp.com/&quot;&gt;http://www.eventlogxp.com/&lt;/a&gt;&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;margin: 0in 0in 0pt;&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;margin: 0in 0in 0pt;&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;margin: 0in 0in 0pt;&quot;&gt;&lt;strong&gt;And a whole list of the other great tools from the IIS Team at Microsoft:&lt;/strong&gt;&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;margin: 0in 0in 0pt;&quot;&gt;&lt;a href=&quot;http://www.iis.net/download/All&quot;&gt;http://www.iis.net/download/All&lt;/a&gt;&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;margin: 0in 0in 0pt;&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;margin: 0in 0in 0pt;&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;margin: 0in 0in 0pt;&quot;&gt;&amp;nbsp;&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;margin: 0in 0in 0pt;&quot;&gt;&amp;nbsp;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dave-black.blogspot.com/feeds/5798599954425766857/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://dave-black.blogspot.com/2011/03/iis-tools-that-you-should-have.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7674671342760410218/posts/default/5798599954425766857'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7674671342760410218/posts/default/5798599954425766857'/><link rel='alternate' type='text/html' href='http://dave-black.blogspot.com/2011/03/iis-tools-that-you-should-have.html' title='IIS Tools that you should have...'/><author><name>Dave Black</name><uri>http://www.blogger.com/profile/11787334586939943513</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEghXqyOIYI80jcRqlgdIPg99-1bldyR6NKQgYGs8Uq_88qc_HNUrHXqM0R_9FvephlqkYzrrmMwMjSs7JV9QVSQAZMlO5hinHcLQrYmcSTRbCS-g4JIfIJaOYteBSxEzGhnZd9T8HJI2sJ86vEVB-Y_6XqfYX3CkdriJnePd8Yrnav-bw/s1600/linked-in-profile-pic-1743640118751.jfif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7674671342760410218.post-1651226130123963380</id><published>2011-03-04T08:18:00.000-06:00</published><updated>2025-02-03T13:48:37.410-06:00</updated><title type='text'>DOT NET TRICKS: Dependency Injection &amp; IOC</title><content type='html'>&lt;a href=&quot;http://www.abhisheksur.com/2011/02/dependency-injection-ioc.html&quot;&gt;DOT NET TRICKS: Dependency Injection &amp;amp; IOC&lt;/a&gt;</content><link rel='replies' type='application/atom+xml' href='http://dave-black.blogspot.com/feeds/1651226130123963380/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://dave-black.blogspot.com/2011/03/dot-net-tricks-dependency-injection-ioc.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7674671342760410218/posts/default/1651226130123963380'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7674671342760410218/posts/default/1651226130123963380'/><link rel='alternate' type='text/html' href='http://dave-black.blogspot.com/2011/03/dot-net-tricks-dependency-injection-ioc.html' title='DOT NET TRICKS: Dependency Injection &amp; IOC'/><author><name>Dave Black</name><uri>http://www.blogger.com/profile/11787334586939943513</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEghXqyOIYI80jcRqlgdIPg99-1bldyR6NKQgYGs8Uq_88qc_HNUrHXqM0R_9FvephlqkYzrrmMwMjSs7JV9QVSQAZMlO5hinHcLQrYmcSTRbCS-g4JIfIJaOYteBSxEzGhnZd9T8HJI2sJ86vEVB-Y_6XqfYX3CkdriJnePd8Yrnav-bw/s1600/linked-in-profile-pic-1743640118751.jfif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7674671342760410218.post-5428466894943873380</id><published>2011-03-02T13:47:00.008-06:00</published><updated>2025-02-03T13:45:14.520-06:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="best practices"/><category scheme="http://www.blogger.com/atom/ns#" term="dispose"/><category scheme="http://www.blogger.com/atom/ns#" term="memory management"/><category scheme="http://www.blogger.com/atom/ns#" term="patterns"/><title type='text'>How do you properly implement the IDisposable pattern?</title><content type='html'>&lt;a href=&quot;http://www.codeproject.com/script/Articles/BlogFeedList.aspx?amid=3680616&quot; rel=&quot;tag&quot; style=&quot;display: none;&quot;&gt;CodeProject&lt;/a&gt;
This is the first post of a series that I&#39;ll be making on memory management in .NET.&amp;nbsp;
    The subsequent posts will cover guidelines for working with disposable objects,
    when to implement IDisposable, and maybe a few others.&lt;br /&gt;
&lt;br /&gt;
I am often asked how to correctly implement the IDisposable pattern. There are many
    posts you&#39;ll see from a Google search that try to answer this question. IMHO, the
    pattern that you find here is the safest and most correct implementation of the
    pattern according to .NET Best Practices and my experience. I am confident saying
    this because of my extensive experience with memory leak debugging, internals of
    the CLR, code reviews, and implementation of best practices at very large, well-known
    clients who rely on solid applications.&amp;nbsp; You will find that my provided implementation
    of this pattern is slightly different than that which is posted on MSDN.&amp;nbsp; IMHO,
    it isn&#39;t sufficient.&amp;nbsp; You have to agree that a large number of samples and
    examples posted on MSDN are &quot;hacky&quot; and don&#39;t do things the way that they should
    be done in the &quot;real world&quot;.&lt;br /&gt;
&lt;br /&gt;
A couple of notes on implementing the IDisposable pattern:&lt;br /&gt;
&lt;ol&gt;
&lt;li&gt;Simply adding a Dispose() method to a class doesn&#39;t implement the pattern (just
            because it compiles doesn&#39;t mean it&#39;s correct).&amp;nbsp; I&#39;ve seen this mistake made
            many, many times - it&#39;s just not a good idea.&lt;/li&gt;
&lt;li&gt;Adding the code below isn&#39;t enough - you must also explicitly declare the class
            inheriting from IDisposable -&amp;gt;&amp;nbsp; MyDisposableClass : IDisposable.&amp;nbsp; This is very important since objects creating/managing instances of your class might decide to try to cast it to IDisposable and call Dispose or use a &#39;using()&#39; statement. If your class isn&#39;t explicitly declared to implement IDisposable, the cast will fail and Dispose will never be called.&lt;/li&gt;
&lt;li&gt;Just because you implement IDisposable correctly doesn&#39;t mean it will get called &quot;magically&quot;. What I mean is that the GC never calls Dispose for you - you have to explicitly call it on your class from the owning object.&amp;nbsp; There is a common misconception that this can somehow magically happen by the GC and that it&#39;s not important that you explicitly call it &quot;because the GC cleans up for you&quot; (WRONG!)&lt;/li&gt;
&lt;li&gt;Implementing the IDisposable pattern correctly is tricky and can easily lead to
            problems if not done properly.&amp;nbsp; This is why I&#39;ve provided the code below.&lt;/li&gt;
&lt;li&gt;I use a code snippet with the exact code below to &lt;u&gt;properly and consistently&lt;/u&gt;
            implement the pattern correctly.&lt;/li&gt;
&lt;li&gt;There is great debate on whether or not you should null out rooted references. It
            certainly never hurts to do so. Nulling these out does do something before GC runs
            - it removes the rooted reference to that object. The GC later scans its collection
            of rooted references and collects those that do not have a rooted reference.
            &lt;br /&gt;
            &lt;br /&gt;
            Think of this example when it is good to do so: you have an instance of type &quot;ClassA&quot;
            - let&#39;s call it &#39;X&#39;. X contains an object of type &quot;ClassB&quot; - let&#39;s call this &#39;Y&#39;.
            Y implements IDisposable, thus, X should do the same to dispose of Y. Let&#39;s assume
            that X is in Generation 2 or the LOH and Y is in Generation 0 or 1. When Dispose()
            is called on X AND that implementation nulls out the reference to Y, the rooted
            reference to Y is immediately removed. If a GC happens for Gen 0 or Gen 1, the memory/resources
            for Y is cleaned up but the memory/resources for X is not since X lives in Gen 2
            or the LOH.&lt;/li&gt;
&lt;/ol&gt;
Here is the code for properly implementing the IDisposable pattern in a &lt;u&gt;base class&lt;/u&gt;:&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;color: blue;&quot;&gt;&lt;/span&gt;
    &lt;br /&gt;
&lt;pre style=&quot;background: white; color: black; font-family: Consolas; font-size: 13px;&quot;&gt;&lt;span style=&quot;color: blue;&quot;&gt;#region&lt;/span&gt;&amp;nbsp;IDisposable&amp;nbsp;base-class implementation
 
&lt;span style=&quot;color: green;&quot;&gt;//TODO&amp;nbsp;remember&amp;nbsp;to&amp;nbsp;make&amp;nbsp;this&amp;nbsp;class&amp;nbsp;inherit&amp;nbsp;from&amp;nbsp;IDisposable&amp;nbsp;-&amp;gt;&amp;nbsp;MyDisposableClass&amp;nbsp;:&amp;nbsp;IDisposable&lt;/span&gt;
 
&lt;span style=&quot;color: grey;&quot;&gt;///&lt;/span&gt;&lt;span style=&quot;color: green;&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: grey;&quot;&gt;&amp;lt;summary&amp;gt;&lt;/span&gt;
&lt;span style=&quot;color: grey;&quot;&gt;///&lt;/span&gt;&lt;span style=&quot;color: green;&quot;&gt;&amp;nbsp;Gets&amp;nbsp;or&amp;nbsp;sets&amp;nbsp;a&amp;nbsp;value&amp;nbsp;indicating&amp;nbsp;whether&amp;nbsp;this&amp;nbsp;instance&amp;nbsp;is&amp;nbsp;disposed.&lt;/span&gt;
&lt;span style=&quot;color: grey;&quot;&gt;///&lt;/span&gt;&lt;span style=&quot;color: green;&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: grey;&quot;&gt;&amp;lt;/summary&amp;gt;&lt;/span&gt;
&lt;span style=&quot;color: grey;&quot;&gt;///&lt;/span&gt;&lt;span style=&quot;color: green;&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: grey;&quot;&gt;&amp;lt;value&amp;gt;&lt;/span&gt;
&lt;span style=&quot;color: grey;&quot;&gt;///&lt;/span&gt;&lt;span style=&quot;color: green;&quot;&gt;&amp;nbsp; &lt;/span&gt;&lt;span style=&quot;color: grey;&quot;&gt;&amp;lt;c&amp;gt;&lt;/span&gt;&lt;span style=&quot;color: green;&quot;&gt;true&lt;/span&gt;&lt;span style=&quot;color: grey;&quot;&gt;&amp;lt;/c&amp;gt;&lt;/span&gt;&lt;span style=&quot;color: green;&quot;&gt;&amp;nbsp;if&amp;nbsp;this&amp;nbsp;instance&amp;nbsp;is&amp;nbsp;disposed;&amp;nbsp;otherwise,&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: grey;&quot;&gt;&amp;lt;c&amp;gt;&lt;/span&gt;&lt;span style=&quot;color: green;&quot;&gt;false&lt;/span&gt;&lt;span style=&quot;color: grey;&quot;&gt;&amp;lt;/c&amp;gt;&lt;/span&gt;&lt;span style=&quot;color: green;&quot;&gt;.&lt;/span&gt;
&lt;span style=&quot;color: grey;&quot;&gt;///&lt;/span&gt;&lt;span style=&quot;color: green;&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: grey;&quot;&gt;&amp;lt;/value&amp;gt;&lt;/span&gt;
&lt;span style=&quot;color: grey;&quot;&gt;///&lt;/span&gt;&lt;span style=&quot;color: green;&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: grey;&quot;&gt;&amp;lt;remarks&amp;gt;&lt;/span&gt;&lt;span style=&quot;color: green;&quot;&gt;Default&amp;nbsp;initialization&amp;nbsp;for&amp;nbsp;a&amp;nbsp;bool&amp;nbsp;is&amp;nbsp;&#39;false&#39;&lt;/span&gt;&lt;span style=&quot;color: grey;&quot;&gt;&amp;lt;/remarks&amp;gt;&lt;/span&gt;
&lt;span style=&quot;color: blue;&quot;&gt;private&lt;/span&gt;&amp;nbsp;&lt;span style=&quot;color: blue;&quot;&gt;bool&lt;/span&gt;&amp;nbsp;IsDisposed&amp;nbsp;{&amp;nbsp;&lt;span style=&quot;color: blue;&quot;&gt;get&lt;/span&gt;;&amp;nbsp;&lt;span style=&quot;color: blue;&quot;&gt;set&lt;/span&gt;;&amp;nbsp;}
 
&lt;span style=&quot;color: grey;&quot;&gt;///&lt;/span&gt;&lt;span style=&quot;color: green;&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: grey;&quot;&gt;&amp;lt;summary&amp;gt;&lt;/span&gt;
&lt;span style=&quot;color: grey;&quot;&gt;///&lt;/span&gt;&lt;span style=&quot;color: green;&quot;&gt;&amp;nbsp;Implementation&amp;nbsp;of&amp;nbsp;Dispose&amp;nbsp;according&amp;nbsp;to&amp;nbsp;.NET&amp;nbsp;Framework&amp;nbsp;Design&amp;nbsp;Guidelines.&lt;/span&gt;
&lt;span style=&quot;color: grey;&quot;&gt;///&lt;/span&gt;&lt;span style=&quot;color: green;&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: grey;&quot;&gt;&amp;lt;/summary&amp;gt;&lt;/span&gt;
&lt;span style=&quot;color: grey;&quot;&gt;///&lt;/span&gt;&lt;span style=&quot;color: green;&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: grey;&quot;&gt;&amp;lt;remarks&amp;gt;&lt;/span&gt;&lt;span style=&quot;color: green;&quot;&gt;Do&amp;nbsp;not&amp;nbsp;make&amp;nbsp;this&amp;nbsp;method&amp;nbsp;virtual.&lt;/span&gt;
&lt;span style=&quot;color: grey;&quot;&gt;///&lt;/span&gt;&lt;span style=&quot;color: green;&quot;&gt;&amp;nbsp;A&amp;nbsp;derived&amp;nbsp;class&amp;nbsp;should&amp;nbsp;not&amp;nbsp;be&amp;nbsp;able&amp;nbsp;to&amp;nbsp;override&amp;nbsp;this&amp;nbsp;method.&lt;/span&gt;
&lt;span style=&quot;color: grey;&quot;&gt;///&lt;/span&gt;&lt;span style=&quot;color: green;&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: grey;&quot;&gt;&amp;lt;/remarks&amp;gt;&lt;/span&gt;
&lt;span style=&quot;color: blue;&quot;&gt;public&lt;/span&gt;&amp;nbsp;&lt;span style=&quot;color: blue;&quot;&gt;void&lt;/span&gt;&amp;nbsp;Dispose()
{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Dispose(&lt;span style=&quot;color: blue;&quot;&gt;true&lt;/span&gt;);
 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style=&quot;color: green;&quot;&gt;//&amp;nbsp;This&amp;nbsp;object&amp;nbsp;will&amp;nbsp;be&amp;nbsp;cleaned&amp;nbsp;up&amp;nbsp;by&amp;nbsp;the&amp;nbsp;Dispose&amp;nbsp;method.&lt;/span&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style=&quot;color: green;&quot;&gt;//&amp;nbsp;Therefore,&amp;nbsp;you&amp;nbsp;should&amp;nbsp;call&amp;nbsp;GC.SupressFinalize&amp;nbsp;to&lt;/span&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style=&quot;color: green;&quot;&gt;//&amp;nbsp;take&amp;nbsp;this&amp;nbsp;object&amp;nbsp;off&amp;nbsp;the&amp;nbsp;finalization&amp;nbsp;queue&amp;nbsp;&lt;/span&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style=&quot;color: green;&quot;&gt;//&amp;nbsp;and&amp;nbsp;prevent&amp;nbsp;finalization&amp;nbsp;code&amp;nbsp;for&amp;nbsp;this&amp;nbsp;object&lt;/span&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style=&quot;color: green;&quot;&gt;//&amp;nbsp;from&amp;nbsp;executing&amp;nbsp;a&amp;nbsp;second&amp;nbsp;time.&lt;/span&gt;
 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style=&quot;color: green;&quot;&gt;//&amp;nbsp;Always&amp;nbsp;use&amp;nbsp;SuppressFinalize()&amp;nbsp;in&amp;nbsp;case&amp;nbsp;a&amp;nbsp;subclass&lt;/span&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style=&quot;color: green;&quot;&gt;//&amp;nbsp;of&amp;nbsp;this&amp;nbsp;type&amp;nbsp;implements&amp;nbsp;a&amp;nbsp;finalizer.&lt;/span&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style=&quot;color: #2b91af;&quot;&gt;GC&lt;/span&gt;.SuppressFinalize(&lt;span style=&quot;color: blue;&quot;&gt;this&lt;/span&gt;);
}
 
&lt;span style=&quot;color: grey;&quot;&gt;///&lt;/span&gt;&lt;span style=&quot;color: green;&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: grey;&quot;&gt;&amp;lt;summary&amp;gt;&lt;/span&gt;
&lt;span style=&quot;color: grey;&quot;&gt;///&lt;/span&gt;&lt;span style=&quot;color: green;&quot;&gt;&amp;nbsp;Overloaded&amp;nbsp;Implementation&amp;nbsp;of&amp;nbsp;Dispose.&lt;/span&gt;
&lt;span style=&quot;color: grey;&quot;&gt;///&lt;/span&gt;&lt;span style=&quot;color: green;&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: grey;&quot;&gt;&amp;lt;/summary&amp;gt;&lt;/span&gt;
&lt;span style=&quot;color: grey;&quot;&gt;///&lt;/span&gt;&lt;span style=&quot;color: green;&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: grey;&quot;&gt;&amp;lt;param&amp;nbsp;name=&lt;/span&gt;&lt;span style=&quot;color: grey;&quot;&gt;&quot;isDisposing&quot;&lt;/span&gt;&lt;span style=&quot;color: grey;&quot;&gt;&amp;gt;&amp;lt;c&amp;gt;&lt;/span&gt;&lt;span style=&quot;color: green;&quot;&gt;true&lt;/span&gt;&lt;span style=&quot;color: grey;&quot;&gt;&amp;lt;/c&amp;gt;&lt;/span&gt;&lt;span style=&quot;color: green;&quot;&gt;&amp;nbsp;to&amp;nbsp;release&amp;nbsp;both&amp;nbsp;managed&amp;nbsp;and&amp;nbsp;unmanaged&amp;nbsp;resources;&amp;nbsp;&lt;/span&gt;
&lt;span style=&quot;color: grey;&quot;&gt;///&lt;/span&gt;&lt;span style=&quot;color: green;&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: grey;&quot;&gt;&amp;lt;c&amp;gt;&lt;/span&gt;&lt;span style=&quot;color: green;&quot;&gt;false&lt;/span&gt;&lt;span style=&quot;color: grey;&quot;&gt;&amp;lt;/c&amp;gt;&lt;/span&gt;&lt;span style=&quot;color: green;&quot;&gt;&amp;nbsp;to&amp;nbsp;release&amp;nbsp;only&amp;nbsp;unmanaged&amp;nbsp;resources.&lt;/span&gt;&lt;span style=&quot;color: grey;&quot;&gt;&amp;lt;/param&amp;gt;&lt;/span&gt;
&lt;span style=&quot;color: grey;&quot;&gt;///&lt;/span&gt;&lt;span style=&quot;color: green;&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: grey;&quot;&gt;&amp;lt;remarks&amp;gt;&lt;/span&gt;
&lt;span style=&quot;color: grey;&quot;&gt;///&lt;/span&gt;&lt;span style=&quot;color: green;&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: grey;&quot;&gt;&amp;lt;list&amp;nbsp;type=&lt;/span&gt;&lt;span style=&quot;color: grey;&quot;&gt;&quot;bulleted&quot;&lt;/span&gt;&lt;span style=&quot;color: grey;&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span style=&quot;color: green;&quot;&gt;Dispose(bool&amp;nbsp;isDisposing)&amp;nbsp;executes&amp;nbsp;in&amp;nbsp;two&amp;nbsp;distinct&amp;nbsp;scenarios.&lt;/span&gt;
&lt;span style=&quot;color: grey;&quot;&gt;///&lt;/span&gt;&lt;span style=&quot;color: green;&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: grey;&quot;&gt;&amp;lt;item&amp;gt;&lt;/span&gt;&lt;span style=&quot;color: green;&quot;&gt;If&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: grey;&quot;&gt;&amp;lt;paramref&amp;nbsp;name=&lt;/span&gt;&lt;span style=&quot;color: grey;&quot;&gt;&quot;isDisposing&quot;&lt;/span&gt;&lt;span style=&quot;color: grey;&quot;&gt;/&amp;gt;&lt;/span&gt;&lt;span style=&quot;color: green;&quot;&gt;&amp;nbsp;equals&amp;nbsp;true,&amp;nbsp;the&amp;nbsp;method&amp;nbsp;has&amp;nbsp;been&amp;nbsp;called&amp;nbsp;directly&lt;/span&gt;
&lt;span style=&quot;color: grey;&quot;&gt;///&lt;/span&gt;&lt;span style=&quot;color: green;&quot;&gt;&amp;nbsp;or&amp;nbsp;indirectly&amp;nbsp;by&amp;nbsp;a&amp;nbsp;user&#39;s&amp;nbsp;code.&amp;nbsp;Managed&amp;nbsp;and&amp;nbsp;unmanaged&amp;nbsp;resources&lt;/span&gt;
&lt;span style=&quot;color: grey;&quot;&gt;///&lt;/span&gt;&lt;span style=&quot;color: green;&quot;&gt;&amp;nbsp;can&amp;nbsp;be&amp;nbsp;disposed.&lt;/span&gt;&lt;span style=&quot;color: grey;&quot;&gt;&amp;lt;/item&amp;gt;&lt;/span&gt;
&lt;span style=&quot;color: grey;&quot;&gt;///&lt;/span&gt;&lt;span style=&quot;color: green;&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: grey;&quot;&gt;&amp;lt;item&amp;gt;&lt;/span&gt;&lt;span style=&quot;color: green;&quot;&gt;If&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: grey;&quot;&gt;&amp;lt;paramref&amp;nbsp;name=&lt;/span&gt;&lt;span style=&quot;color: grey;&quot;&gt;&quot;isDisposing&quot;&lt;/span&gt;&lt;span style=&quot;color: grey;&quot;&gt;/&amp;gt;&lt;/span&gt;&lt;span style=&quot;color: green;&quot;&gt;&amp;nbsp;equals&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: grey;&quot;&gt;&amp;lt;c&amp;gt;&lt;/span&gt;&lt;span style=&quot;color: green;&quot;&gt;false&lt;/span&gt;&lt;span style=&quot;color: grey;&quot;&gt;&amp;lt;/c&amp;gt;&lt;/span&gt;&lt;span style=&quot;color: green;&quot;&gt;,&amp;nbsp;the&amp;nbsp;method&amp;nbsp;has&amp;nbsp;been&amp;nbsp;called&amp;nbsp;&lt;/span&gt;&lt;/pre&gt;
&lt;pre style=&quot;background: white; color: black; font-family: Consolas; font-size: 13px;&quot;&gt;&lt;span style=&quot;color: grey;&quot;&gt;///&lt;/span&gt;&lt;span style=&quot;color: green;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: green;&quot;&gt;by&amp;nbsp;the&lt;/span&gt;&lt;span style=&quot;color: green;&quot;&gt; runtime&amp;nbsp;from&amp;nbsp;inside&amp;nbsp;the&amp;nbsp;finalizer&amp;nbsp;and&amp;nbsp;you&amp;nbsp;should&amp;nbsp;not&amp;nbsp;reference&lt;/span&gt;
&lt;span style=&quot;color: grey;&quot;&gt;///&lt;/span&gt;&lt;span style=&quot;color: green;&quot;&gt;&amp;nbsp;other&amp;nbsp;objects.&amp;nbsp;Only&amp;nbsp;unmanaged&amp;nbsp;resources&amp;nbsp;can&amp;nbsp;be&amp;nbsp;disposed.&lt;/span&gt;&lt;span style=&quot;color: grey;&quot;&gt;&amp;lt;/item&amp;gt;&amp;lt;/list&amp;gt;&lt;/span&gt;
&lt;span style=&quot;color: grey;&quot;&gt;///&lt;/span&gt;&lt;span style=&quot;color: green;&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: grey;&quot;&gt;&amp;lt;/remarks&amp;gt;&lt;/span&gt;
&lt;span style=&quot;color: blue;&quot;&gt;protected&lt;/span&gt;&amp;nbsp;&lt;span style=&quot;color: blue;&quot;&gt;virtual&lt;/span&gt;&amp;nbsp;&lt;span style=&quot;color: blue;&quot;&gt;void&lt;/span&gt;&amp;nbsp;Dispose(&lt;span style=&quot;color: blue;&quot;&gt;bool&lt;/span&gt;&amp;nbsp;isDisposing)
{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style=&quot;color: green;&quot;&gt;//&amp;nbsp;TODO&amp;nbsp;If&amp;nbsp;you&amp;nbsp;need&amp;nbsp;thread&amp;nbsp;safety,&amp;nbsp;use&amp;nbsp;a&amp;nbsp;lock&amp;nbsp;around&amp;nbsp;these&amp;nbsp;&lt;/span&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style=&quot;color: green;&quot;&gt;//&amp;nbsp;operations,&amp;nbsp;as&amp;nbsp;well&amp;nbsp;as&amp;nbsp;in&amp;nbsp;your&amp;nbsp;methods&amp;nbsp;that&amp;nbsp;use&amp;nbsp;the&amp;nbsp;resource.&lt;/span&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style=&quot;color: blue;&quot;&gt;try&lt;/span&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=&quot;color: blue;&quot;&gt;if&lt;/span&gt;&amp;nbsp;(!&lt;span style=&quot;color: blue;&quot;&gt;this&lt;/span&gt;.IsDisposed)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{
&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=&quot;color: green;&quot;&gt;//&amp;nbsp;Explicitly&amp;nbsp;set&amp;nbsp;root&amp;nbsp;references&amp;nbsp;to&amp;nbsp;null&amp;nbsp;to&amp;nbsp;expressly&amp;nbsp;tell&amp;nbsp;the&amp;nbsp;GarbageCollector&lt;/span&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=&quot;color: green;&quot;&gt;//&amp;nbsp;that&amp;nbsp;the&amp;nbsp;resources&amp;nbsp;have&amp;nbsp;been&amp;nbsp;disposed&amp;nbsp;of&amp;nbsp;and&amp;nbsp;its&amp;nbsp;ok&amp;nbsp;to&amp;nbsp;release&amp;nbsp;the&amp;nbsp;memory&amp;nbsp;
            // allocated&amp;nbsp;for&amp;nbsp;them.&lt;/span&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=&quot;color: blue;&quot;&gt;if&lt;/span&gt;&amp;nbsp;(isDisposing)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&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=&quot;color: green;&quot;&gt;//&amp;nbsp;Release&amp;nbsp;all&amp;nbsp;managed&amp;nbsp;resources&amp;nbsp;here&lt;/span&gt;&lt;/pre&gt;
&lt;pre style=&quot;background: white; color: black; font-family: Consolas; font-size: 13px;&quot;&gt;&lt;/pre&gt;
&lt;pre style=&quot;background: white; color: black; font-family: Consolas; font-size: 13px;&quot;&gt;&lt;/pre&gt;
&lt;pre style=&quot;background: white; color: black; font-family: Consolas; font-size: 13px;&quot;&gt;&lt;span style=&quot;color: green;&quot;&gt;                // Need to unregister/detach yourself from the events. Always make sure&lt;/span&gt;
&lt;span style=&quot;color: green;&quot;&gt;                // the object is not null first before trying to unregister/detach them!
                // Failure to unregister can be a BIG source of memory leaks&lt;/span&gt;
                &lt;span style=&quot;color: blue;&quot;&gt;if&lt;/span&gt;&amp;nbsp;(someDisposableObjectWithAnEventHandler != null)
                {                 
                    someDisposableObjectWithAnEventHandler.SomeEvent -= someDelegate;
                    someDisposableObjectWithAnEventHandler.Dispose();
                    someDisposableObjectWithAnEventHandler = &lt;span style=&quot;color: blue;&quot;&gt;null&lt;/span&gt;;
                }&lt;/pre&gt;
&lt;pre style=&quot;background: white; color: black; font-family: Consolas; font-size: 13px;&quot;&gt;&lt;/pre&gt;
&lt;pre style=&quot;background: white; color: black; font-family: Consolas; font-size: 13px;&quot;&gt;&lt;/pre&gt;
&lt;pre style=&quot;background: white; color: black; font-family: Consolas; font-size: 13px;&quot;&gt;&lt;span style=&quot;color: green;&quot;&gt;                //&amp;nbsp;If&amp;nbsp;this&amp;nbsp;is&amp;nbsp;a&amp;nbsp;WinForm/UI&amp;nbsp;control,&amp;nbsp;uncomment&amp;nbsp;this&amp;nbsp;code&lt;/span&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;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style=&quot;color: green;&quot;&gt;//if&amp;nbsp;(components&amp;nbsp;!=&amp;nbsp;null)&lt;/span&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;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style=&quot;color: green;&quot;&gt;//{&lt;/span&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;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style=&quot;color: green;&quot;&gt;//&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;components.Dispose();&lt;/span&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;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style=&quot;color: green;&quot;&gt;//}&lt;/span&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;/pre&gt;
&lt;pre style=&quot;background: white; color: black; font-family: Consolas; font-size: 13px;&quot;&gt;&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=&quot;color: green;&quot;&gt;//&amp;nbsp;Release&amp;nbsp;all&amp;nbsp;unmanaged&amp;nbsp;resources&amp;nbsp;here&lt;/span&gt; &amp;nbsp;&lt;/pre&gt;
&lt;div style=&quot;background: white; color: black; font-family: Consolas; font-size: 13px;&quot;&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=&quot;color: green;&quot;&gt;//&amp;nbsp;(example)&lt;/span&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=&quot;color: blue;&quot;&gt;if&lt;/span&gt;&amp;nbsp;(someComObject&amp;nbsp;!=&amp;nbsp;&lt;span style=&quot;color: blue;&quot;&gt;null&lt;/span&gt;&amp;nbsp;&amp;amp;&amp;amp;&amp;nbsp;&lt;span style=&quot;color: #2b91af;&quot;&gt;Marshal&lt;/span&gt;.IsComObject(someComObject))&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&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;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style=&quot;color: #2b91af;&quot;&gt;Marshal&lt;/span&gt;.FinalReleaseComObject(someComObject);&lt;br /&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;&amp;nbsp;&amp;nbsp;&amp;nbsp; someComObject
    =&amp;nbsp;&lt;span style=&quot;color: blue;&quot;&gt;null&lt;/span&gt;;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }
    &lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style=&quot;color: blue;&quot;&gt;finally&lt;/span&gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style=&quot;color: blue;&quot;&gt;this&lt;/span&gt;.IsDisposed&amp;nbsp;=&amp;nbsp;&lt;span style=&quot;color: blue;&quot;&gt;true&lt;/span&gt;;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;div style=&quot;color: green;&quot;&gt;//TODO&amp;nbsp;Uncomment&amp;nbsp;this&amp;nbsp;code&amp;nbsp;if&amp;nbsp;this&amp;nbsp;class&amp;nbsp;will&amp;nbsp;contain&amp;nbsp;members&amp;nbsp;which&amp;nbsp;are&amp;nbsp;UNmanaged&lt;/div&gt;
    &lt;div style=&quot;color: green;&quot;&gt;/////&amp;nbsp;&amp;lt;summary&amp;gt;Finalizer&amp;nbsp;for MyDisposableClass&amp;lt;/summary&amp;gt;&lt;/div&gt;
    &lt;div style=&quot;color: green;&quot;&gt;/////&amp;nbsp;&amp;lt;remarks&amp;gt;This&amp;nbsp;finalizer&amp;nbsp;will&amp;nbsp;run&amp;nbsp;only&amp;nbsp;if&amp;nbsp;the&amp;nbsp;Dispose&amp;nbsp;method&amp;nbsp;does&amp;nbsp;not&amp;nbsp;get&amp;nbsp;called.&lt;/div&gt;
    &lt;div style=&quot;color: green;&quot;&gt;/////&amp;nbsp;It&amp;nbsp;gives&amp;nbsp;your&amp;nbsp;base&amp;nbsp;class&amp;nbsp;the&amp;nbsp;opportunity&amp;nbsp;to&amp;nbsp;finalize.&lt;/div&gt;
    &lt;div style=&quot;color: green;&quot;&gt;/////&amp;nbsp;DO&amp;nbsp;NOT&amp;nbsp;provide&amp;nbsp;finalizers&amp;nbsp;in&amp;nbsp;types&amp;nbsp;derived&amp;nbsp;from&amp;nbsp;this&amp;nbsp;class.&lt;/div&gt;
    &lt;div style=&quot;color: green;&quot;&gt;/////&amp;nbsp;All&amp;nbsp;code&amp;nbsp;executed&amp;nbsp;within&amp;nbsp;a&amp;nbsp;Finalizer&amp;nbsp;MUST&amp;nbsp;be&amp;nbsp;thread-safe!&amp;lt;/remarks&amp;gt;&lt;/div&gt;
    &lt;div style=&quot;color: green;&quot;&gt;//&amp;nbsp;&amp;nbsp;~MyDisposableClass()&lt;/div&gt; &lt;div style=&quot;color: green;&quot;&gt;
        //&amp;nbsp;&amp;nbsp;{&lt;/div&gt; &lt;div style=&quot;color: green;&quot;&gt;// &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Dispose(&amp;nbsp;false&amp;nbsp;);&lt;/div&gt;
    &lt;div style=&quot;color: green;&quot;&gt;//&amp;nbsp;&amp;nbsp;}&lt;/div&gt; &lt;div&gt;&lt;span style=&quot;color: blue;&quot;&gt;#endregion&lt;/span&gt;&amp;nbsp;IDisposable&amp;nbsp;base-class
    implementation&lt;/div&gt;
&lt;/div&gt;
&lt;pre style=&quot;background: white; color: black; font-family: Consolas; font-size: 13px;&quot;&gt;&amp;nbsp;&lt;/pre&gt;
&lt;span style=&quot;color: black;&quot;&gt;Here is the code for properly implementing the IDisposable
        pattern in a&amp;nbsp;&lt;u&gt;derived class&lt;/u&gt;:&lt;/span&gt;&lt;br /&gt;
&lt;div style=&quot;background: white; color: black; font-family: Consolas; font-size: 13px;&quot;&gt;
&lt;br /&gt;
&lt;span style=&quot;color: blue;&quot;&gt;#region&lt;/span&gt;&amp;nbsp;IDisposable&amp;nbsp;derived-class implementation&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;color: grey;&quot;&gt;///&lt;/span&gt;&lt;span style=&quot;color: green;&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: grey;&quot;&gt;&amp;lt;summary&amp;gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;color: grey;&quot;&gt;///&lt;/span&gt;&lt;span style=&quot;color: green;&quot;&gt;&amp;nbsp;Gets&amp;nbsp;or&amp;nbsp;sets&amp;nbsp;a&amp;nbsp;value&amp;nbsp;indicating&amp;nbsp;whether&amp;nbsp;this&amp;nbsp;instance&amp;nbsp;is&amp;nbsp;disposed.&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;color: grey;&quot;&gt;///&lt;/span&gt;&lt;span style=&quot;color: green;&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: grey;&quot;&gt;&amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;color: grey;&quot;&gt;///&lt;/span&gt;&lt;span style=&quot;color: green;&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: grey;&quot;&gt;&amp;lt;value&amp;gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;color: grey;&quot;&gt;///&lt;/span&gt;&lt;span style=&quot;color: green;&quot;&gt;&amp;nbsp; &lt;/span&gt;&lt;span style=&quot;color: grey;&quot;&gt;&amp;lt;c&amp;gt;&lt;/span&gt;&lt;span style=&quot;color: green;&quot;&gt;true&lt;/span&gt;&lt;span style=&quot;color: grey;&quot;&gt;&amp;lt;/c&amp;gt;&lt;/span&gt;&lt;span style=&quot;color: green;&quot;&gt;&amp;nbsp;if&amp;nbsp;this&amp;nbsp;instance&amp;nbsp;is&amp;nbsp;disposed;&amp;nbsp;otherwise,&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: grey;&quot;&gt;&amp;lt;c&amp;gt;&lt;/span&gt;&lt;span style=&quot;color: green;&quot;&gt;false&lt;/span&gt;&lt;span style=&quot;color: grey;&quot;&gt;&amp;lt;/c&amp;gt;&lt;/span&gt;&lt;span style=&quot;color: green;&quot;&gt;.&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;color: grey;&quot;&gt;///&lt;/span&gt;&lt;span style=&quot;color: green;&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: grey;&quot;&gt;&amp;lt;/value&amp;gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;color: grey;&quot;&gt;///&lt;/span&gt;&lt;span style=&quot;color: green;&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: grey;&quot;&gt;&amp;lt;remarks&amp;gt;&lt;/span&gt;&lt;span style=&quot;color: green;&quot;&gt;Default&amp;nbsp;initialization&amp;nbsp;for&amp;nbsp;a&amp;nbsp;bool&amp;nbsp;is&amp;nbsp;&#39;false&#39;&lt;/span&gt;&lt;span style=&quot;color: grey;&quot;&gt;&amp;lt;/remarks&amp;gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;color: blue;&quot;&gt;private&lt;/span&gt;&amp;nbsp;&lt;span style=&quot;color: blue;&quot;&gt;bool&lt;/span&gt;&amp;nbsp;IsDisposed&amp;nbsp;{&amp;nbsp;&lt;span style=&quot;color: blue;&quot;&gt;get&lt;/span&gt;;&amp;nbsp;&lt;span style=&quot;color: blue;&quot;&gt;set&lt;/span&gt;;&amp;nbsp;}&lt;/div&gt;
&lt;div style=&quot;background: white; color: black; font-family: Consolas; font-size: 13px;&quot;&gt;
&lt;br /&gt;
&lt;span style=&quot;color: grey;&quot;&gt;///&lt;/span&gt;&lt;span style=&quot;color: green;&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: grey;&quot;&gt;&amp;lt;summary&amp;gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;color: grey;&quot;&gt;///&lt;/span&gt;&lt;span style=&quot;color: green;&quot;&gt;&amp;nbsp;Overloaded&amp;nbsp;Implementation&amp;nbsp;of&amp;nbsp;Dispose.&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;color: grey;&quot;&gt;///&lt;/span&gt;&lt;span style=&quot;color: green;&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: grey;&quot;&gt;&amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;color: grey;&quot;&gt;///&lt;/span&gt;&lt;span style=&quot;color: green;&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: grey;&quot;&gt;&amp;lt;param&amp;nbsp;name=&lt;/span&gt;&lt;span style=&quot;color: grey;&quot;&gt;&quot;isDisposing&quot;&lt;/span&gt;&lt;span style=&quot;color: grey;&quot;&gt;&amp;gt;&amp;lt;c&amp;gt;&lt;/span&gt;&lt;span style=&quot;color: green;&quot;&gt;true&lt;/span&gt;&lt;span style=&quot;color: grey;&quot;&gt;&amp;lt;/c&amp;gt;&lt;/span&gt;&lt;span style=&quot;color: green;&quot;&gt;&amp;nbsp;to&amp;nbsp;release&amp;nbsp;both&amp;nbsp;managed&amp;nbsp;and&amp;nbsp;unmanaged&amp;nbsp;resources;&amp;nbsp;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;color: grey;&quot;&gt;///&lt;/span&gt;&lt;span style=&quot;color: green;&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: grey;&quot;&gt;&amp;lt;c&amp;gt;&lt;/span&gt;&lt;span style=&quot;color: green;&quot;&gt;false&lt;/span&gt;&lt;span style=&quot;color: grey;&quot;&gt;&amp;lt;/c&amp;gt;&lt;/span&gt;&lt;span style=&quot;color: green;&quot;&gt;&amp;nbsp;to&amp;nbsp;release&amp;nbsp;only&amp;nbsp;unmanaged&amp;nbsp;resources.&lt;/span&gt;&lt;span style=&quot;color: grey;&quot;&gt;&amp;lt;/param&amp;gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;color: grey;&quot;&gt;///&lt;/span&gt;&lt;span style=&quot;color: green;&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: grey;&quot;&gt;&amp;lt;remarks&amp;gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;color: grey;&quot;&gt;///&lt;/span&gt;&lt;span style=&quot;color: green;&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: grey;&quot;&gt;&amp;lt;list&amp;nbsp;type=&lt;/span&gt;&lt;span style=&quot;color: grey;&quot;&gt;&quot;bulleted&quot;&lt;/span&gt;&lt;span style=&quot;color: grey;&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span style=&quot;color: green;&quot;&gt;Dispose(bool&amp;nbsp;isDisposing)&amp;nbsp;executes&amp;nbsp;in&amp;nbsp;two&amp;nbsp;distinct&amp;nbsp;scenarios.&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;color: grey;&quot;&gt;///&lt;/span&gt;&lt;span style=&quot;color: green;&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: grey;&quot;&gt;&amp;lt;item&amp;gt;&lt;/span&gt;&lt;span style=&quot;color: green;&quot;&gt;If&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: grey;&quot;&gt;&amp;lt;paramref&amp;nbsp;name=&lt;/span&gt;&lt;span style=&quot;color: grey;&quot;&gt;&quot;isDisposing&quot;&lt;/span&gt;&lt;span style=&quot;color: grey;&quot;&gt;/&amp;gt;&lt;/span&gt;&lt;span style=&quot;color: green;&quot;&gt;&amp;nbsp;equals&amp;nbsp;true,&amp;nbsp;the&amp;nbsp;method&amp;nbsp;has&amp;nbsp;been&amp;nbsp;called&amp;nbsp;directly&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;color: grey;&quot;&gt;///&lt;/span&gt;&lt;span style=&quot;color: green;&quot;&gt;&amp;nbsp;or&amp;nbsp;indirectly&amp;nbsp;by&amp;nbsp;a&amp;nbsp;user&#39;s&amp;nbsp;code.&amp;nbsp;Managed&amp;nbsp;and&amp;nbsp;unmanaged&amp;nbsp;resources&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;color: grey;&quot;&gt;///&lt;/span&gt;&lt;span style=&quot;color: green;&quot;&gt;&amp;nbsp;can&amp;nbsp;be&amp;nbsp;disposed.&lt;/span&gt;&lt;span style=&quot;color: grey;&quot;&gt;&amp;lt;/item&amp;gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;color: grey;&quot;&gt;///&lt;/span&gt;&lt;span style=&quot;color: green;&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: grey;&quot;&gt;&amp;lt;item&amp;gt;&lt;/span&gt;&lt;span style=&quot;color: green;&quot;&gt;If&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: grey;&quot;&gt;&amp;lt;paramref&amp;nbsp;name=&lt;/span&gt;&lt;span style=&quot;color: grey;&quot;&gt;&quot;isDisposing&quot;&lt;/span&gt;&lt;span style=&quot;color: grey;&quot;&gt;/&amp;gt;&lt;/span&gt;&lt;span style=&quot;color: green;&quot;&gt;&amp;nbsp;equals&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: grey;&quot;&gt;&amp;lt;c&amp;gt;&lt;/span&gt;&lt;span style=&quot;color: green;&quot;&gt;false&lt;/span&gt;&lt;span style=&quot;color: grey;&quot;&gt;&amp;lt;/c&amp;gt;&lt;/span&gt;&lt;span style=&quot;color: green;&quot;&gt;,&amp;nbsp;the&amp;nbsp;method&amp;nbsp;has&amp;nbsp;been&amp;nbsp;called&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;color: grey;&quot;&gt;///&lt;/span&gt;&lt;span style=&quot;color: green;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: green;&quot;&gt;by&amp;nbsp;the &lt;/span&gt;&lt;span style=&quot;color: green;&quot;&gt;runtime&amp;nbsp;from&amp;nbsp;inside&amp;nbsp;the&amp;nbsp;finalizer&amp;nbsp;and&amp;nbsp;you&amp;nbsp;should&amp;nbsp;not&amp;nbsp;reference&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;color: grey;&quot;&gt;///&lt;/span&gt;&lt;span style=&quot;color: green;&quot;&gt;&amp;nbsp;other&amp;nbsp;objects.&amp;nbsp;Only&amp;nbsp;unmanaged&amp;nbsp;resources&amp;nbsp;can&amp;nbsp;be&amp;nbsp;disposed.&lt;/span&gt;&lt;span style=&quot;color: grey;&quot;&gt;&amp;lt;/item&amp;gt;&amp;lt;/list&amp;gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;color: grey;&quot;&gt;///&lt;/span&gt;&lt;span style=&quot;color: green;&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: grey;&quot;&gt;&amp;lt;/remarks&amp;gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;color: blue;&quot;&gt;protected&lt;/span&gt;&amp;nbsp;&lt;span style=&quot;color: blue;&quot;&gt;override&lt;/span&gt;&amp;nbsp;&lt;span style=&quot;color: blue;&quot;&gt;void&lt;/span&gt;&amp;nbsp;Dispose(&lt;span style=&quot;color: blue;&quot;&gt;bool&lt;/span&gt;&amp;nbsp;isDisposing)&lt;br /&gt;
{&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style=&quot;color: green;&quot;&gt;//&amp;nbsp;TODO&amp;nbsp;If&amp;nbsp;you&amp;nbsp;need&amp;nbsp;thread&amp;nbsp;safety,&amp;nbsp;use&amp;nbsp;a&amp;nbsp;lock&amp;nbsp;around&amp;nbsp;these&amp;nbsp;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style=&quot;color: green;&quot;&gt;//&amp;nbsp;operations,&amp;nbsp;as&amp;nbsp;well&amp;nbsp;as&amp;nbsp;in&amp;nbsp;your&amp;nbsp;methods&amp;nbsp;that&amp;nbsp;use&amp;nbsp;the&amp;nbsp;resource.&lt;/span&gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style=&quot;color: blue;&quot;&gt;try&lt;/span&gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style=&quot;color: blue;&quot;&gt;if&lt;/span&gt;&amp;nbsp;(!&lt;span style=&quot;color: blue;&quot;&gt;this&lt;/span&gt;.IsDisposed)&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br /&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=&quot;color: green;&quot;&gt;//&amp;nbsp;Explicitly&amp;nbsp;set&amp;nbsp;root&amp;nbsp;references&amp;nbsp;to&amp;nbsp;null&amp;nbsp;to&amp;nbsp;expressly&amp;nbsp;tell&amp;nbsp;the&amp;nbsp;GarbageCollector&lt;/span&gt;&lt;br /&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=&quot;color: green;&quot;&gt;//&amp;nbsp;that&amp;nbsp;the&amp;nbsp;resources&amp;nbsp;have&amp;nbsp;been&amp;nbsp;disposed&amp;nbsp;of&amp;nbsp;and&amp;nbsp;its&amp;nbsp;ok&amp;nbsp;to&amp;nbsp;release&amp;nbsp;the&amp;nbsp;memory&amp;nbsp;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;color: green;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
            // allocated&amp;nbsp;for&amp;nbsp;them.&lt;/span&gt;&lt;br /&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=&quot;color: blue;&quot;&gt;if&lt;/span&gt;&amp;nbsp;(isDisposing)&lt;br /&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;br /&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;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style=&quot;color: green;&quot;&gt;//&amp;nbsp;Release&amp;nbsp;all&amp;nbsp;managed&amp;nbsp;resources&amp;nbsp;here&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;pre style=&quot;background: white; color: black; font-family: Consolas; font-size: 13px;&quot;&gt;&lt;span style=&quot;color: green;&quot;&gt;                // Need to unregister/detach yourself from the events. Always make sure&lt;/span&gt;
&lt;span style=&quot;color: green;&quot;&gt;                // the object is not null first before trying to unregister/detach them!
                // Failure to unregister can be a BIG source of memory leaks&lt;/span&gt;
                &lt;span style=&quot;color: blue;&quot;&gt;if&lt;/span&gt;&amp;nbsp;(someDisposableObjectWithAnEventHandler != null)
                {                 
                    someDisposableObjectWithAnEventHandler.SomeEvent -= someDelegate;
                    someDisposableObjectWithAnEventHandler.Dispose();
                    someDisposableObjectWithAnEventHandler = &lt;span style=&quot;color: blue;&quot;&gt;null&lt;/span&gt;;
                }
&lt;/pre&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;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style=&quot;color: green;&quot;&gt;//&amp;nbsp;If&amp;nbsp;this&amp;nbsp;is&amp;nbsp;a&amp;nbsp;WinForm/UI&amp;nbsp;contrlol,&amp;nbsp;uncomment&amp;nbsp;this&amp;nbsp;code&lt;/span&gt;&lt;br /&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;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style=&quot;color: green;&quot;&gt;//if&amp;nbsp;(components&amp;nbsp;!=&amp;nbsp;null)&lt;/span&gt;&lt;br /&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;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style=&quot;color: green;&quot;&gt;//{&lt;/span&gt;&lt;br /&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;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style=&quot;color: green;&quot;&gt;//&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;components.Dispose();&lt;/span&gt;&lt;br /&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;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style=&quot;color: green;&quot;&gt;//}&lt;/span&gt;&lt;br /&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;br /&gt;
&lt;br /&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=&quot;color: green;&quot;&gt;//&amp;nbsp;Release&amp;nbsp;all&amp;nbsp;unmanaged&amp;nbsp;resources&amp;nbsp;here&lt;/span&gt;&lt;/div&gt;
&lt;pre style=&quot;background: white; color: black; font-family: Consolas; font-size: 13px;&quot;&gt;&amp;nbsp;&lt;/pre&gt;
&lt;pre style=&quot;background: white; color: black; font-family: Consolas; font-size: 13px;&quot;&gt;&amp;nbsp;&lt;/pre&gt;
&lt;div style=&quot;background: white; color: black; font-family: Consolas; font-size: 13px;&quot;&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=&quot;color: green;&quot;&gt;//&amp;nbsp;(example)&lt;/span&gt;&lt;br /&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=&quot;color: blue;&quot;&gt;if&lt;/span&gt;&amp;nbsp;(someComObject&amp;nbsp;!=&amp;nbsp;&lt;span style=&quot;color: blue;&quot;&gt;null&lt;/span&gt;&amp;nbsp;&amp;amp;&amp;amp;&amp;nbsp;&lt;span style=&quot;color: #2b91af;&quot;&gt;Marshal&lt;/span&gt;.IsComObject(someComObject))&lt;br /&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;br /&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;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style=&quot;color: #2b91af;&quot;&gt;Marshal&lt;/span&gt;.FinalReleaseComObject(someComObject);&lt;br /&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;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;someComObject
        =&amp;nbsp;&lt;span style=&quot;color: blue;&quot;&gt;null&lt;/span&gt;;&lt;br /&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;/div&gt;
&lt;div style=&quot;background: white; color: black; font-family: Consolas; font-size: 13px;&quot;&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style=&quot;color: blue;&quot;&gt;finally&lt;/span&gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br /&gt;
&lt;span style=&quot;color: blue;&quot;&gt;&lt;span style=&quot;color: black;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: blue;&quot;&gt;this&lt;/span&gt;&lt;span style=&quot;color: black;&quot;&gt;.IsDisposed&amp;nbsp;=&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: blue;&quot;&gt;true&lt;/span&gt;&lt;span style=&quot;color: black;&quot;&gt;;&lt;/span&gt;&lt;span style=&quot;color: green;&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;color: blue;&quot;&gt;&lt;span style=&quot;color: green;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
            //&amp;nbsp;explicitly&amp;nbsp;call&amp;nbsp;the&amp;nbsp;base&amp;nbsp;class&amp;nbsp;Dispose&amp;nbsp;implementation&lt;/span&gt;&lt;br /&gt;
            &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style=&quot;color: blue;&quot;&gt;base&lt;/span&gt;.&lt;span style=&quot;color: black;&quot;&gt;Dispose(isDisposing);&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;
}&lt;/div&gt;
&lt;div style=&quot;background: white; color: black; font-family: Consolas; font-size: 13px;&quot;&gt;
&lt;/div&gt;
&lt;div style=&quot;background: white; color: black; font-family: Consolas; font-size: 13px;&quot;&gt;
&lt;span style=&quot;color: blue;&quot;&gt;#endregion&lt;/span&gt;&amp;nbsp;IDisposable&amp;nbsp;derived-class implementation&lt;/div&gt;
&lt;div style=&quot;background: white; color: black; font-family: Consolas; font-size: 13px;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;br /&gt;</content><link rel='replies' type='application/atom+xml' href='http://dave-black.blogspot.com/feeds/5428466894943873380/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://dave-black.blogspot.com/2011/03/how-do-you-properly-implement.html#comment-form' title='13 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7674671342760410218/posts/default/5428466894943873380'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7674671342760410218/posts/default/5428466894943873380'/><link rel='alternate' type='text/html' href='http://dave-black.blogspot.com/2011/03/how-do-you-properly-implement.html' title='How do you properly implement the IDisposable pattern?'/><author><name>Dave Black</name><uri>http://www.blogger.com/profile/11787334586939943513</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEghXqyOIYI80jcRqlgdIPg99-1bldyR6NKQgYGs8Uq_88qc_HNUrHXqM0R_9FvephlqkYzrrmMwMjSs7JV9QVSQAZMlO5hinHcLQrYmcSTRbCS-g4JIfIJaOYteBSxEzGhnZd9T8HJI2sJ86vEVB-Y_6XqfYX3CkdriJnePd8Yrnav-bw/s1600/linked-in-profile-pic-1743640118751.jfif'/></author><thr:total>13</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7674671342760410218.post-4176237386622394007</id><published>2011-02-24T11:04:00.015-06:00</published><updated>2025-02-03T13:45:32.528-06:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="debugging"/><category scheme="http://www.blogger.com/atom/ns#" term="IIS"/><category scheme="http://www.blogger.com/atom/ns#" term="tools"/><title type='text'>Tools for Assisting with Collection and Analyzing of Data for Problem Diagnosis</title><content type='html'>I was going through my Google Bookmarks and found a bunch of tools that are extremely helpful in &lt;u&gt;diagnosing&lt;/u&gt;&amp;nbsp; many problems that occur on a web/app server and and &lt;u&gt;interpreting&lt;/u&gt; the data collected.  I’ve used all of them; they are all free and well known and used within the Community.&amp;nbsp; By no means is this an exhaustive list of all of the Tools and Add-Ins that I use - I&#39;ll get around to posting those someday : )&lt;br /&gt;
&lt;br /&gt;
I’d start with the Data Collector.  You can collect everything with Data Collector and then use the Log Parser and Visual Log Parser to help aggregate the data and even run queries against it.  You may already know about some of these – but for those you haven’t seen, you should take a look!&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Data Collector (supports IIS6 &amp;amp; IIS7, and can pull most other logs from any server):&lt;/b&gt;&lt;br /&gt;
&lt;a href=&quot;http://blogs.msdn.com/b/carloc/archive/2010/02/01/idevdatacollector.aspx&quot; target=&quot;tools&quot;&gt;http://blogs.msdn.com/b/carloc/archive/2010/02/01/idevdatacollector.aspx&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Log Parser 2.2:&lt;/b&gt;&lt;br /&gt;
&lt;a href=&quot;http://www.microsoft.com/downloads/en/details.aspx?FamilyID=890cd06b-abf8-4c25-91b2-f8d975cf8c07&amp;amp;displaylang=en&quot; target=&quot;tools&quot;&gt;http://www.microsoft.com/downloads/en/details.aspx?FamilyID=890cd06b-abf8-4c25-91b2-f8d975cf8c07&amp;amp;displaylang=en&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Visual Log Parser:&lt;/b&gt;&lt;br /&gt;
&lt;a href=&quot;http://visuallogparser.codeplex.com/&quot; target=&quot;tools&quot;&gt;http://visuallogparser.codeplex.com/&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Log File Analysis:&lt;/b&gt;&lt;br /&gt;
&lt;a href=&quot;http://blogs.msdn.com/b/delay/archive/2007/06/21/powerful-log-file-analysis-for-everyone-releasing-textanalysistool-net.aspx&quot; target=&quot;tools&quot;&gt;http://blogs.msdn.com/b/delay/archive/2007/06/21/powerful-log-file-analysis-for-everyone-releasing-textanalysistool-net.aspx&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Event Log Explorer:&lt;/b&gt;&lt;br /&gt;
&lt;a href=&quot;http://www.eventlogxp.com/&quot; target=&quot;tools&quot;&gt;http://www.eventlogxp.com/&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;IIS Log Analyzer (does graphs and reports):&lt;/b&gt;&lt;br /&gt;
&lt;a href=&quot;http://www.iis.net/community/default.aspx?tabid=34&amp;amp;g=6&amp;amp;i=1864&quot; target=&quot;tools&quot;&gt;http://www.iis.net/community/default.aspx?tabid=34&amp;amp;g=6&amp;amp;i=1864&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;IIS Diagnostics Toolkit (a suite of tools diagnosing Authentication, Authorization, SSL, Crash/Hang, etc.):&lt;/b&gt;&lt;br /&gt;
&lt;a href=&quot;http://www.microsoft.com/downloads/en/details.aspx?FamilyID=9bfa49bc-376b-4a54-95aa-73c9156706e7&quot; target=&quot;tools&quot;&gt;http://www.microsoft.com/downloads/en/details.aspx?FamilyID=9bfa49bc-376b-4a54-95aa-73c9156706e7&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;and then of course the &quot;big daddy&quot; bunch of them all - Debugging Tools for Windows:&lt;/b&gt;&lt;br /&gt;
&lt;a href=&quot;http://www.microsoft.com/whdc/devtools/debugging/default.mspx&quot; target=&quot;tools&quot;&gt;http://www.microsoft.com/whdc/devtools/debugging/default.mspx&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
I hope you find these useful : )</content><link rel='replies' type='application/atom+xml' href='http://dave-black.blogspot.com/feeds/4176237386622394007/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://dave-black.blogspot.com/2011/02/tools-for-assisting-with-collection-and.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7674671342760410218/posts/default/4176237386622394007'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7674671342760410218/posts/default/4176237386622394007'/><link rel='alternate' type='text/html' href='http://dave-black.blogspot.com/2011/02/tools-for-assisting-with-collection-and.html' title='Tools for Assisting with Collection and Analyzing of Data for Problem Diagnosis'/><author><name>Dave Black</name><uri>http://www.blogger.com/profile/11787334586939943513</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEghXqyOIYI80jcRqlgdIPg99-1bldyR6NKQgYGs8Uq_88qc_HNUrHXqM0R_9FvephlqkYzrrmMwMjSs7JV9QVSQAZMlO5hinHcLQrYmcSTRbCS-g4JIfIJaOYteBSxEzGhnZd9T8HJI2sJ86vEVB-Y_6XqfYX3CkdriJnePd8Yrnav-bw/s1600/linked-in-profile-pic-1743640118751.jfif'/></author><thr:total>0</thr:total></entry></feed>