Tag Archive for .NET

Not-So-Lazy Static Constructors in C# 4.0

A coworker pointed me towards an interesting blog post by John Skeet about the changed behavior of static constructors in C# 4.0 (yes, I know, it’s been a few years now, but I never ran into it).

It seems that C# 4.0 now tries to be lazier when instantiated static fields. So if I have a side-effect free static method that doesn’t touch any members, calling it will not bother initializing the static fields. From Skeet’s post:

  1. class Lazy
  2.     {
  3.         private static int x = Log();
  4.         private static int Log()
  5.         {
  6.             Console.WriteLine(“Type initialized”);
  7.             return 0;
  8.         }
  9.         public static void StaticMethod()
  10.         {
  11.             Console.WriteLine(“In static method”);
  12.         }
  13.     }

Calling StaticMethod() will print “In static method”, but will not print “Type Initialized”!

This was a bit worrying. John Skeet said it shouldn’t impact existing code, but we were not so sure. Imagine a class whose static constructor does some unmanaged initialization work (creates a Performance Counter, for instance) while the static method  writes to the counter. This could potentially cause a hard to find exception, since our expectation was that static constructors can be relied upon to always be called first.

So we ran a quick test (and by “we” I most mean Amir), and it seems that this behavior isn’t as problematic as we thought. Look at this code, adding a static constructor to the class above:

  1. class Lazy
  2.     {
  3.         private static int x = Log();
  4.         private static int Log()
  5.         {
  6.             Console.WriteLine(“Type initialized”);
  7.             return 0;
  8.         }
  9.  
  10.         static Lazy()
  11.         {
  12.             Console.WriteLine(“In static constructor”);
  13.         }
  14.  
  15.         public static void StaticMethod()
  16.         {
  17.             Console.WriteLine(“In static method”);
  18.         }
  19.     }

The only difference is that we have an explicit static constructor, rather than the implicit one that initializes the field. Unlike the first test case, in this case calling StaticMethod() did call the static constructor, and we could see “In static constructor” printed before “In static method”. The compiler is smart enough to see that we have an explicit constructor defined, so that means we want it to be called, and it will be called. This was reassuring.

But wait, there’s more! It seems that once type initialization was triggered by the presence of the explicit static constructor, it went all the way. Even the x parameter was initialized, the Log() method was called, and “Type Initialized” was printed to the console, even before the static constructor. This was the behavior I was used to, where static field initializations are added to the beginning of the .cctor.

To summarize, the new lazy type initialization behavior for C# 4.0 is interesting, since it allows static classes that contain only side-effect free methods (for instance, classes containing popular Extension Methods) to avoid expensive and unnecessary initializations. But it was designed smartly enough to recognize when initialization is explicitly desired, and be a bit less lazy in that case.

(And thanks again to Igal Tabachnik and Amir Zuker)

Remote Debugging through fire, snow or fog

Remote Debugging in Visual Studio is a wonderful feature, especially during the later stages of testing and deployment, and even (if all else fails) when in production, but getting it to work is rarely smooth. Everything is fine if both the computer running VS and the one running the application are in the same domain, but when they aren’t, things start to break, fast. I

So for those stuck debugging remote applications in different domains, here’s a quick guide to east the pain.

  1. On the the remote machine, install the Visual Studio Remote Debugging package, which comes with the version of Visual Studio you’re using.
  2. On the remote machine, create a new local user account. Give it the exact same name and password that you use on your development machine.
    If you’re developing when logged into MYCORPDOMAINMyUserName, with password MYPASS123, you wil have to create a local user REMOTEMACHINEMyUserName with the same password. It doesn’t matter that the domains are different and there’s no trust relationship and so forth. Just have them be the same username and password.
  3. Give REMOTEMACHINEMyUserName permissions. Administrator permissions is the safest, though you should be able to get it to work with a more restricted group, but I haven’t checked it yet.
  4. Run the application you want to debug using the MyUserName credentials. In Windows 7, this means using Shift-Rightclick and choosing Run As Different User. For Vista, there’s a shell extension to enable it.
  5. Run the Remote Debugging program, again under MyUserName credentials, same as above. The Remote Debugger will start with a new session named MyUserName@REMOTEMACHINE.
  6. Copy the remote debugging session name from the remote machine (you can copy it via the Tools –> Options menu).
  7. In your development machine, open Visual Studio, and go to Debug –> Attach to Process.
  8. In the Attack to Process screen, paste the remote debugging session name into the Qualifier textbox (the second one from the top).
  9. Voila! You are now debugging remotely!

The Case of the Unexpected Expected Exception

“NUnit is being problematic again”, they told me when I came to visit the project. “When running unattended it’s not catching assertions properly and the test is coming up green, but when stepping through in the debugger, it works fine.”. It’s nice, when getting a passing test is acknowledged as a bad thing, at least when you don’t expect it to be. In this case, though, the fault wasn’t really with NUnit.

  1: [Test]
  2: [ExpectedException]
  3: public void DoTheTest()
  4: {
  5:     _myComponent.RunMethod();
  6:     Assert.IsFalse(_myComponent.EverythingIsFine);
  7: }

“It’s simple. Either the method throws an exception, or at the very least – the EverythingIsFine property won’t be set to “True”, so the assert will catch the problem. But in their case, no exception was thrown and Everything wasn’t Fine,  but the Assert call wasn’t raising a red flag – unless they stepped through, in which case it did. What’s going on?

The basic problem is that to many developers, NUnit is a kind of magic. You write a self-contained little bit of code, the [Test] method, but you don’t call it yourself, you don’t get a feel for the whole execution flow. The result – developers don’t exercise the same sort of judgement they do on their own application code.

The root of the problem here is that the [ExpectedException] attribute told NUnit to pass the test if an exception is thrown. NUnit’s Assertion utilities, however, use exceptions as the mechanism for failing tests – when an assertion is hit, it raises an exception – it can be an AssertionException. For various mock frameworks, it can be an ExpectationException. It doesn’t matter – it’s these exceptions that make the test fail, and not some behind-the-scenes magic. Because the test had an open-ended [ExpectedException] attribute, these exceptions were caught, fulfilling the condition, and NUnit was happy.

What can we do to avoid this?

  • Be explicit. Don’t try to catch ALL exceptions with [ExpectedException]. If you’re expecting an exception, you’re probably expecting a specific exception. Specify it.
  • Be aware of how your tools work. If NUnit works by throwing an exception, don’t wrap it with a try/catch. Your tests are C# code too, as is the plumbing to enable it. It plays by the same rules.

Tales from the Unmanaged Side – System.String –> char* (pt. 2)

A while ago, I posted an entry about marshalling a managed System.String into an unmanaged C string, specifically a plain char*. The solution I suggested, back in 2007, involved calling Marshal::StringToHGlobalAuto method to allocate memory and copy the string data into it, and then cast the HGlobal pointer into a char*.

It seems that in Visual Studio 2008 a new way of doing it was added, as part of the new Marshalling Library. This library provides a whole set of conversions between System.String and popular unmanaged string representations, like char*, wchar_t*, BSTR, CStringT and others I am even less familiar with.

The smarter string representations, like std::string, have their own destructors so I can carelessly let them drop out of scope without worrying about leaks. The more primitive ones, like char*, need to be explicitly released, so that’s why the Marshalling Library contains a new (managed) class called marshal_context which gives me exactly this explicit release.

Let’s compare my old code with the new:

   1:  const char* unmanagedString = NULL;
   2:  try
   3:  {
   4:      String^ managedString = gcnew String("managed string");
   5:      // Note the double cast.
   6:      unmanagedString = (char*)(void*)Marshal::StringToHGlobalAnsi(managedString);
   7:  }
   8:  finally
   9:  {
  10:      // Don't forget to release. Note the ugly casts again.
  11:      Marshal::FreeHGlobal((IntPtr)(void*)unmanagedString);
  12:  }

And the new:

   1:  marshal_context^ context = gcnew marshal_context();
   2:  String^ managedString = gcnew String("managed string");
   3:  const char* unmanagedString = context->marshal_as<const char*>( managedString );
 

Much shorter, I’m sure you’ll agree. And neater – no need for all the icky, icky casting between different pointer types. And most importantly, I don’t have to explicitly release the char* – the marshal_context class keeps a reference to all the strings that were marshalled through it, and when it goes out of scope its destructor makes sure to release them all. Very efficient, all in all.

Static Constructor throws the same exception again and again

Here’s a little gotcha I ran into today – if you have code in a class’s static constructor that throws an exception, we will get a TypeInitializationException with the original exception as the InnerException – so far, nothing new.

However, if we keep on calling methods on that object, we’ll keep receiving TypeInitializationExceptions. If it cannot be initialized, it cannot be called. Every time we try, we’ll receive the exact same exception. However, the static ctor will not be called again. What appears to happen is that the CLR caches the TypeInitializationException object itself, InnerException included, and rethrows it whenever the type is called.

What are the ramifications? Well, we received an OutOfMemoryException in our static ctor, but the outer exception was caught and tried again. So we got an OutOfMemoryException again, even though the memory problem was behind us, which sent us down the wrong track of looking for persistent memory problems. Theoretically, it could also be a leak – the inner exception holding some sort of reference that is never released, but that’s an edge case.

Here’s some code to illustrate the problem. The output clearly shows that while we wait a second between calls, the inner exception contains the time of the original exception, not any subsequent calls. Debugging also shows that the static ctor is called only once.

   1:  class Program
   2:  {
   3:      static void Main(string[] args)
   4:      {
   5:   
   6:          for (int i = 0; i < 5; i++)
   7:          {
   8:              try
   9:              {
  10:                  Thread.Sleep(1000);
  11:                  StaticClass.Method();
  12:   
  13:              }
  14:              catch (Exception ex)
  15:              {
  16:                  Console.WriteLine(ex.InnerException.Message);
  17:              }
  18:          }
  19:   
  20:          Console.ReadLine();
  21:      }
  22:  }
  23:   
  24:  static class StaticClass
  25:  {
  26:      static StaticClass()
  27:      {
  28:          throw new Exception("Exception thrown at " + DateTime.Now.ToString());
  29:      }
  30:   
  31:      public static void Method()
  32:      { }
  33:   
  34:  }

Upgrading all projects to .NET 3.5

A simple macro to change the Target Framework for a project from .NET 2.0 to .NET 3.5, hacked together in a few minutes. This will fail for C++/CLI projects, and possibly VB.NET projects (haven’t checked). Works fine for regular C# projects, as well as web projects:

 

For Each proj As Project In DTE.Solution.Projects
   Try
       proj.Properties.Item("TargetFramework").Value = 196613
       Debug.Print("Upgraded {0} to 3.5", proj.Name)
   Catch ex As Exception
       Debug.Print("Failed to upgrade {0} to 3.5", proj.Name)
   End Try

Next proj

Why 196613, you ask? Well, when I see such a number my first instinct is to feed it into calc.exe and switch it to hexadecimal. And I was right: 196613 in decimal converts to 0x00030005 – You can see the framework version hiding in there. Major version in the high word, minor in the low word. The previous TargetFramework number was 131072 – 0x00020000, or 2.0.

 

(Nitpickers might point out that I could simply set it to &30005 rather than messing with the obscure decimal number. They would be correct – but I got to this number through the debugger, so that’s how it will stay)

Any signs of life for the SharePoint Extensions for Visual Studio?

Has anything been released – or, in fact, talked about – since August’s release of the v1.1 CTP?

Haven’t done any web-part development in a while and wanted to get back in the game. I last used the v1.0 extensions, and was surprised that nothing much has changed in that field except for the CTP release, and even that can’t be downloaded – I just get a broken link.

Seeking advice – strong names and config files

I’ll use my blog for a bit of fishing for advice and guidance on an issue that’s been bugging me.

We’ve been moving towards using strong names on all of our assemblies. The benefits are obvious, and it’s a must before we deploy to clients out in the wild.

The problem is that we have several different processes running, each with its own app.config or web.config file. These config files contain references to custom configuration sections, whether they’re application configuration, Enterprise Library extensions or whatnot. Seeing as my DLLs are signed, I have to use the fully qualified assembly name in all my references. This means that in a nightly build scenario where my version number is bumped continuously, I have to change 5-6 references in 5-6 configuration files with every build.

Doing this kind of string manipulation on a large scale scares me, since it can break, or we miss something. I’ve tried using and directives, but they require a specific version to point to as well.

 

I’m sure I’m not the first person to encounter this problem. What are the solutions that you use to bypass this? Scripts as part of the automated installation? Moving all configuration sections to a separate assembly whose version is static? What’s the least painful way to manage this?

System.Diagnostics.EventLogEntry and the non-equal Equals.

Just a quick heads-up in case you’re stumped with this problem, or just passing by:

The System.Diagnostics.EventLogEntry class implements the Equals method to check if two entries are identical, even if they’re not the same instance. However, contrary to best practices, it does NOT overload the operator==, so these two bits of code will behave differently:

EventLog myEventLog = new EventLog("Application");
EventLogEntry entry1 = myEventLog.Entries[0];
EventLogEntry entry2 = myEventLog.Entries[0];

bool correct = entry1.Equals(entry2);
bool incorrect = entry1 == entry2;

After running this code, correct will be true while incorrect will be false.

Good to know, if you’re reading event logs in your code.

Displaying live log file contents

I’m writing some benchmarking code, which involves a Console application calling a COM+ hosted process and measuring performance. I want to constantly display results on my active console, but since some of my code is running out-of-process, I can’t really write directly to the console from all parts of the system. Not to mention the fact that I want it logged to a file as well.

So I cobbled together a quick Log class that does two things – it writes to a shared log file, keeping no locks so several processes can access it (I do serialize access to the WriteLine method itself, though). I don’t mind the overhead of opening/closing the file every time, since this isn’t production code.

The second method is the interesting one – it monitors the log file and returns every new line that is appended to it. If no lines are available, it will block until one is reached. The fun part was using the yield return keyword, which I’ve been looking for an excuse to use for quiet a while now.

Note that there are many places this code can go wrong or should be improved. There is no way to stop it running, only when the application is stopped. I bring this as the basic idea, and it can be cleaned up and improved later:

   1: public static IEnumerable<string> ReadNextLineOrBlock()
   2:         {
   3:             // Open the file without locking it.
   4:             using (FileStream logFile = new FileStream(Filename, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
   5:             using (StreamReader reader = new StreamReader(logFile))
   6:             {
   7:                 while (true)
   8:                 {
   9:                     // Read the next line.
  10:                     string line = reader.ReadLine();
  11:                     if (!string.IsNullOrEmpty(line))
  12:                     {
  13:                         yield return line;
  14:                     }
  15:                     else
  16:                     {
  17:                         Thread.Sleep(100);
  18:                     }
  19:                 }
  20:             }
  21:         }

This method can now be called from a worker thread:

 

   1: private static void StartListenerThread()
   2:         {
   3:             Thread t = new Thread(delegate()
   4:             {
   5:                 while (true)
   6:                 {
   7:                     foreach (string line in Log.ReadNextLineOrBlock())
   8:                     {
   9:                         // I added some formatting, too.
  10:                         if (line.Contains("Total"))
  11:                             Console.ForegroundColor = ConsoleColor.Green;
  12:                         
  13:                         Console.WriteLine(line);
  14:  
  15:                         Console.ForegroundColor = ConsoleColor.White;
  16:                     }
  17:                 }
  18:             });
  19:  
  20:             t.Start();
  21:         }