The Black Box of .NET Headline Animator

The Black Box of .NET

Tuesday, March 13, 2012

Don't use 'using()' with a WCF proxy


If you're trying to be a conscientious developer and making sure that you cleanup your resources - great! You are writing 'using()' 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:

    // The IL for this block is effectively the same as
    // the IL for the second block below
    using (var win = new Form())
    {
    }

   
    // This is the second block
    Form f = null;
    try
    {
        f = new Form();
    }
    finally
    {
        if (f != null)
        {
            f.Dispose();
        }
    }

Here's the IL for the 'using()' block above compiled in Release mode:

     IL_0000:  newobj     instance void [System.Windows.Forms]System.Windows.Forms.Form::.ctor()
     IL_0005:  stloc.0
     .try
     {
         IL_0006:  leave.s    IL_0012
     }  // end .try
     finally
     {
         IL_0008:  ldloc.0
         IL_0009:  brfalse.s  IL_0011
         IL_000b:  ldloc.0
         IL_000c:  callvirt   instance void [mscorlib]System.IDisposable::Dispose()
         IL_0011:  endfinally
     }  // end handler


Here's the IL for the second block (try/finally) compiled in Release mode:

     IL_0012:  ldnull
     IL_0013:  stloc.1
     .try
     {
         IL_0014:  newobj     instance void [System.Windows.Forms]System.Windows.Forms.Form::.ctor()
         IL_0019:  stloc.1
         IL_001a:  leave.s    IL_0026
     }  // end .try
     finally
     {
         IL_001c:  ldloc.1
         IL_001d:  brfalse.s  IL_0025
         IL_001f:  ldloc.1
         IL_0020:  callvirt   instance void [System]System.ComponentModel.Component::Dispose()
         IL_0025:  endfinally
     }  // end handler

As you can see, the IL is nearly identical.

Well this is all fine and good but let's get back to the issue with WCF.  The problem is that if an exception is thrown during disposal of the WCF client/proxy, the channel is never closed.  Now, in general, any exception that occurs during disposal of an object is indeed undesirable.  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.

Here is an alternative solution that can be used:

    WCFProxy variableName = null;
    try
    {
        variableName = new WCFProxy();

        // TODO code here

        variableName.Close();
    }
// if you need to catch other exceptions, do so here...
    catch (Exception)
    {
        if (variableName != null)
        {
            variableName.Abort();
        }
        throw;
    }

MSDN does have a brief on this issue which you can read here - http://msdn.microsoft.com/en-us/library/aa355056.aspx

Share

Thursday, January 26, 2012

Why you should comment your code...

Here are the most important reasons for including comments/documentation when writing code:
  1. 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.
  2. 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'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.
  3. What about someone new to your team? What if your the new guy? Is it easier to learn it with or without documentation/comments?
  4. 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't have access to the code? Would you want to have to do this?
  5. What if you find some code without comments and the code looks wrong or inefficient? It's certainly possible that it was written that way for a reason. Only comments would help.
  6. In addition to adding comments, code itself should be self documenting: use descriptive class, member, variable, parameter and method names.
When you write code, remember that you're not always going to be the one modifying, supporting it or consuming it...

Peter Ritchie has a good post about what comments are NOT for - a pretty good read: http://msmvps.com/blogs/peterritchie/archive/2012/01/30/what-code-comments-are-not-for.aspx


Share

Friday, December 9, 2011

Debugging Tools to Diagnose a Memory Leak

Debugging and diagnosing a memory leak or an OutOfMemoryException can be a daunting and challenging task. Fortunately, there are a number of tools to help; some of these are "paid license" apps, but there are even more tools that are free. There is a little bit of irony here; IMHO, the better tools are the free ones...

Free Tools
Licensed Tools
Hope this helps!


Share

Thursday, December 8, 2011

How to Tell if an Assembly is Debug or Release

The DebuggableAttribute is present if you compile in any setting for 'Debug' mode and when Release mode is selected and Debug Info set to anything other than "none". So, just looking for the presence of DebuggableAttribute is not sufficient and could be misleading. So, you could still have an assembly that is JIT optimized where the DebuggableAttribute is present in the Assembly Manifest.

First, you need to define exactly what is meant by "Debug" vs. "Release"...
  • Do you mean that the app is configured with code optimization?
  • Do you mean that you can attach the VS/JIT Debugger to it?
  • Do you mean that it generates DebugOutput?
  • Do you mean that it defines the DEBUG constant?  Remember that you can conditionally compile Methods with the System.Diagnostics.Conditional() attribute.
IMHO, when someone asks whether or not an assembly is "Debug" or "Release", they really mean if the code is optimized...

Sooo, do you want to do this manually or programmatically?

Manually:
You need to view the value of the DebuggableAttribute bitmask for the assembly's metadata.  Here's how to do it:

  1. Open the assembly in ILDASM
  2. Open the Manifest
  3. Look at the DebuggableAttribute bitmask.  If the DebuggableAttribute is not present, it is definitely an Optimized assembly.
  4. If it is present, look at the 4th byte - if it is a '0' it is JIT Optimized - anything else, it is not:
// Metadata version: v4.0.30319
....
     //  .custom instance void [mscorlib]System.Diagnostics.DebuggableAttribute::.ctor(valuetype [mscorlib]System.Diagnostics.DebuggableAttribute/DebuggingModes) = ( 01 00 02 00 00 00 00 00 )

    Programmatically: assuming that you want to know programmatically if the code is JITOptimized, here is the correct implementation:

    void Main()
    {
    	var HasDebuggableAttribute = false;
    	var IsJITOptimized = false;
    	var IsJITTrackingEnabled = false;
    	var BuildType = "";
    	var DebugOutput = "";
    	var ReflectedAssembly = Assembly.LoadFile(@"C:\src\TMDE\Git\RedisScalingTest\bin\Release\netcoreapp3.1\RedisScalingTest.dll");
     
    	//	var ReflectedAssembly = Assembly.LoadFile(@"path to the dll you are testing");
    	object[] attribs = ReflectedAssembly.GetCustomAttributes(typeof(DebuggableAttribute), false);
     
    	// If the 'DebuggableAttribute' is not found then it is definitely an OPTIMIZED build
    	if (attribs.Length > 0)
    	{
    		// Just because the 'DebuggableAttribute' is found doesn't necessarily mean
    		// it's a DEBUG build; we have to check the JIT Optimization flag
    		// i.e. it could have the "generate PDB" checked but have JIT Optimization enabled
    		DebuggableAttribute debuggableAttribute = attribs[0] as DebuggableAttribute;
    		if (debuggableAttribute != null)
    		{
    			HasDebuggableAttribute = true;
    			IsJITOptimized = !debuggableAttribute.IsJITOptimizerDisabled;
     
    			// IsJITTrackingEnabled - Gets a value that indicates whether the runtime will track information during code generation for the debugger.
    			IsJITTrackingEnabled = debuggableAttribute.IsJITTrackingEnabled;
    			BuildType = debuggableAttribute.IsJITOptimizerDisabled ? "Debug" : "Release";
     
    			// check for Debug Output "full" or "pdb-only"
    			DebugOutput = (debuggableAttribute.DebuggingFlags &
    							DebuggableAttribute.DebuggingModes.Default) !=
    							DebuggableAttribute.DebuggingModes.None
    							? "Full" : "pdb-only";
    		}
    	}
    	else
    	{
    		IsJITOptimized = true;
    		BuildType = "Release";
    	}
     
    	Console.WriteLine($"{nameof(HasDebuggableAttribute)}{HasDebuggableAttribute}");
    	Console.WriteLine($"{nameof(IsJITOptimized)}{IsJITOptimized}");
    	Console.WriteLine($"{nameof(IsJITTrackingEnabled)}{IsJITTrackingEnabled}");
    	Console.WriteLine($"{nameof(BuildType)}{BuildType}");
    	Console.WriteLine($"{nameof(DebugOutput)}{DebugOutput}");
    }



    Share

    Friday, July 29, 2011

    My Favorite Quotes

    Here are some of my favorite quotes:

    "Debugging is twice as hard as writing code in the first place.  Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it."
        - Brian Kernighan

    "Intellectuals solve problems; geniuses prevent them."
        - Albert Einstein

    "There are three categories of open issues with our application: those that we know about, those that we don't know about, and those that we don't know that we don't know about."  Someone in the group actually asked "Can you give an example of the last one?"
        - former coworker

    "It's not a bug, it's a feature"
        - unknown

    "Bugs are a form of job security."
        - unknown

    "If debugging is the process of removing bugs, then programming must be the process of putting them in."
      - Edsger Dijkstra

    "The only difference between a beginning programmer and an experienced one is the complexity of the bugs they write."
      - Dave Black
    Share

    Monday, June 6, 2011

    Finally a good free multi-monitor tool

    timstall: Tool - WinSplit Revolution - move windows between ...: "A coworker showed me a useful (and free!) tool that conveniently positions open windows on your screen. The tool is Winsplit Revolution , ..."
    Share

    Friday, April 29, 2011

    New WinDbg Extension available

    I'm happy to announce that a new version of the WinDbg debugging extension PSSCOR2 (now called PSSCOR4) has been released.  It is available for public download here: 

    http://www.microsoft.com/downloads/en/details.aspx?FamilyID=a06a0fea-a4d4-434e-a527-d6afa2e552dd
    Share

    Thursday, April 28, 2011

    Whitepaper on the Debug Diagnostic Tool v1.1 - IIS debugging and debugdiag - Site Home - MSDN Blogs

    Whitepaper on the Debug Diagnostic Tool v1.1 - IIS debugging and debugdiag - Site Home - MSDN Blogs
    Share

    Wednesday, March 9, 2011

    IIS Tools that you should have...

    Here is a list of IIS tools I've used in the past and their respective links.  Please note that all of these tools are FREE and widely used in the industry.
     
    IIS Web Deploy 2.0
     
     
    IIS 6.0 Resource Kit (many tools included here – most helpful are probably IIS 6.0 Migration Tool and the IIS Metabase Explorer)
     
     
    IIS Diagnostics Kit – IIS Diag
     
    This includes a number of tools which help diagnose various types of problems with IIS setup and configuration:
    • AuthDiag - authentication and ACL problems
    • SSL Diag - SSL-related problems
    • SMTP Diag - smtp-related issues
    • Log Parser - allows for easy reading of IIS log files
    • Debug Diag - allows you to create memory dumps manually or automatically when IIS hangs.  It also can run a memory ananlysis from the memory dump captured!
    • and others...

    Event Log Explorer - allows you to create custom queries and filters against anything in the Event Viewer – very cool!


    And a whole list of the other great tools from the IIS Team at Microsoft:


     
     
    Share

    Friday, March 4, 2011

    DOT NET TRICKS: Dependency Injection & IOC

    DOT NET TRICKS: Dependency Injection & IOC
    Share