Dealing with infinite recursion redux

In a previous post about infinite recursion I proposed the use of the ThreadStaticAttribute to deal with infinite recursion. This approach is fine so long as your recursion doesn’t cross threads, if it does the static variable will be reset for each new thread and offer not benefit.

Here’s an example, in .NET 4.0, to show you what I mean. In this example I have a simple logging setup, with a list of IListeners which handle messages that a logged with the LogMessage function. It’ll get into a infinite recursive loop becuase the LogToDiskListener attempts to log a message, and the ThreadStaticAttribute doesn’t help because each listener is executed in it’s own thread.

        [ThreadStatic]
        private static bool _isLoggingMessage;

        private static List<IListener> _listeners = new List<IListener>();

        public static void Main()
        {
            _listeners.Add(new LogToDiskListener());
            LogMessage("Starting main function");
        }

        private static void LogMessage(string message)
        {
            if (_isLoggingMessage)
                return;

            _isLoggingMessage = true;

            _listeners.AsParallel()
                .ForAll(listener => listener.HandleMessage(message));

            _isLoggingMessage = false;
        }

        public class LogToDiskListener : IListener
        {
            public void HandleMessage(string message)
            {
                LogMessage("Writing message to disk");

                // Write the message to disk
            }
        }

        public interface IListener
        {
            void HandleMessage(string message);
        }

The code above won’t throw a StackOverFlowException, but will continue to use CPU and increase memory usage until it starves itself of threads.

Fortunately there is a particular solution to this scenario, using the CallContext.LogicalSetData method. Any data set with this method will continue to flow down through child threads, offering a solution to the recursion. Below is a example that wont loop indefinitely:

        private const string IsLoggingMessageKey = "LoggingExample_IsLoggingMessage";

        private static bool IsLoggingMessage
        {
            get
            {
                return ((bool?)CallContext.LogicalGetData(IsLoggingMessageKey))
                    .GetValueOrDefault();
            }
            set
            {
                CallContext.LogicalSetData(IsLoggingMessageKey, value);
            }
        }

        private static List<IListener> _listeners = new List<IListener>();

        public static void Main()
        {
            _listeners.Add(new LogToDiskListener());
            LogMessage("Starting main function");
        }

        private static void LogMessage(string message)
        {
            if (IsLoggingMessage)
                return;

            _listeners.AsParallel()
                .ForAll(listener =>
                {
                    IsLoggingMessage = true;
                    listener.HandleMessage(message);
                });
        }

        public class LogToDiskListener : IListener
        {
            public void HandleMessage(string message)
            {
                LogMessage("Writing message to disk");

                // Write the message to disk
            }
        }

        public interface IListener
        {
            void HandleMessage(string message);
        }

In the new version of the I’ve replaced the field with a ThreadStaticAttribue with a property that wraps around some calls to the CallContext. I’ve also removed the call to set it to false, since it’s value is lost as soon as all the threads that are using are finished. I’ve also move the place where the new property is set to within the child threads.

Phil

Bookmark and Share

Phil’s 10 Rules for the treatment of Exceptions

You know what I love, Exceptions. Exceptions are awesome.

They’re an awesome tool that simplify post-mortem debugging, help developers code against and understand the internal workings of an API and they help prevent applications getting into a corrupt state.

Even though exceptions are so invaluable, a lot of the time they’re poorly understood, abused, ignored and forgotten. I hope that I can earn some respect for the venerable exception, by setting down some rules on how they should be treated.

Phil’s 10 rules for the treatment of Exceptions:

  1. Throw early, throw often[1]
    This is key tenet of exceptions. You must throw as early as possible. For example, if your method requires a parameter isn’t null, throw an ArgumentNullException as soon as possible, on one of the first lines in the method. An early ArgumentNullException provides much more information than a NullReferenceException later in the code, and an early exception prevents the class getting into a corrupt state.
  2. Prevention is the best medicine
    You should always avoid calling methods that you know will throw an exception only to catch the exception and continue executing. It makes for hard to read code and exceptions have a performance cost, so avoid the exception being thrown in the first place if possible. For example, rather than letting a statement throw a DivideByZeroException, use an ‘if’ statement to check the divisor isn’t zero!
  3. Log each, and every exception (almost)
    Once an application is in Production, or QA, the chances are you’re not going to have a debugger attached so you can see exceptions when they happen, and you’re going to have to rely on post-mortem debugging. This is why you must log everything. All exceptions that aren’t caught must be logged, and 90% of exceptions that are caught should be logged too.
  4. Don’t abuse the BCL exceptions
    Knowing the type of an exception being thrown provides a lot of valuable information, so if the type is a generic base type, debugging all of a sudden becomes a lot harder. Microsoft’s guidelines recommend never throwing System.Exception, and I couldn’t agree more. That class tells you nothing about what’s gone wrong.

    Try to define your own exceptions classes when possible (ideally with the Exception snippet if you’re in C#,) give them descriptive names, meaningful properties and default messages.

  5. Descriptive error messages add context
    Even if you’re throwing the right type of exception, you still need to add details to the exception to give it context, and the best way to do that is with a descriptive message. In the example of a FileNotFoundException, providing the name of the file that was missing would be a pretty good start.
  6. Know that even when you’re not coding an new API, you’re coding an new API
    This is one of my core beliefs in programming, imagine that everything you write is going to be exposed as part of an API. It makes you double think what you write if you’re assuming it’s going to be of the CLR in .net 5.0! With this in mind, think about someone calling your methods, and how they’re going to be able make their own code work when yours is throwing meaningless exceptions, or worse, no exceptions at all.
  7. Catch and wrap
    Catching an exception and making it the inner exception of a new exception allows you to add additional detail, giving even more context. A common networking exception might be WebException: “The underlying connection is closed.” While helpful, probably won’t give you enough info to resolve it. Catching and wrapping it in a new exception “Calling method X on remote server Y” helps tremendously.
  8. Don’t use exceptions when a return value is more appropriate
    While I’d never recommend having a function return a value to indicate whether a function failed or not, I’d also never recommend throwing an exception just because there’s nothing to return. It’s okay to return null if the situation calls for it. For example, if you’re using a file for caching, and the file doesn’t exist, don’t throw a FileNotFoundException, return null since there’s nothing cached.
  9. Know which exception message are and aren’t appropriate for an end user
    While it’s easy to just display the message from an exception to an end user, often they’ll have no idea what it means or how to fix it, no matter how technical they are. You should just try and cover all the common scenarios with custom UI messages, and for the edge cases, logging and ‘send crash report’ type functionality is your friend.
  10. Don’t panic!
    It’s okay, exceptions aren’t a bad thing! A lot of people feel it’s necessary to catch exceptions at every chance they get. A lot of the time it’s better just to leave the exception to bubble up the stack to be handled at the topmost level, especially when the code that catches the exception then carries on as if nothing’s happened, resulting in a corrupt state and unpredictable behaviour.

For those interested in how logging is best done in ASP.NET, you might want to look at my older post.

There’s a lot to think about here, and I’m sure you all have different opinions, is there anything else you’d add to this list?

Phil

[1]A programmer’s introduction to C# 2.0

Bookmark and Share

Anonymous types that look the same, are the same

Anonymous types are one of the features that was introduced as part of .net 3.5, they allow a programmer to make a new type dynamically, with its properties defined from its usage.

An quick example of an anonymous type might be:

var anon = new { AnInteger = 1, AString = "string" };
Console.WriteLine(anon.AString);

Behind the scenes, the compiler will create a class that looks somewhat like this:

class Anon
{
    public int AnInteger { get; private set; }
    public string AString { get; private set; }
}

The type doesn’t look exactly like that, but from a usage point of view, it’s close enough.

There is one important thing that you’ll need to know if you’re dealing with collections of anonymous types, is that if you have two collections of them, and you want to create a union of the two, then they have to be declared in the same way. If the properties name, type and order are exactly the same, the compiler will make them the same anonymous type, allowing them to be stored in the same strongly typed collection.

Given that, the follow example is valid code, and will create a strongly typed array of an anonymous type:

var anon1 = new { AnInteger = 1, AString = "string1" };
var anon2 = new { AnInteger = 2, AString = "string2" };

var unionedList = new[] { anon1, anon2 };

foreach (var item in unionedList)
    Console.WriteLine(item.AString);

As a contrast, here are some alternate definitions of ‘anon2′ that would generate compiler errors at line 4, where the array is created, because the compiler would make ‘anon2′ a different anonymous type:

// Would fail because AnInteger is of type 'string'
var anon2 = new { AnInteger = "2", AString = "string2" };

// Would fail because "AnInteger" is defined on anon1 and "AnIntegerX" is defined here
var anon2 = new { AnIntegerX = 2, AString = "string2" };

// Would fail because the order of the properties is different
var anon2 = new { AString = "string2", AnIntegerX = 2 };
Bookmark and Share

Locking on Value Types

Locking is a core principle when it comes to multi-threaded applications, it allows a program make sure a block of code is executed by only one thread at at time. The lock statement in C#, or SyncLock in VB.net, is a really useful command to quickly create a lock and guarantee that the lock is released when the code finishes, even if it throws an exception.

private static object _lockObject = new object();
private void SomeFunction()
{
    lock(_lockObject)
    {
        // Do something
    }
}

There’s one thing that’ll trip up people new to threading, which is that the .net runtime disallows the locking on value types. This is because the underlying logic for the locking requires a pointer (how reference types are referenced) to be able to distinguish between different locks. If you pass a value type in the runtime will box the value type, meaning you’ll get a different pointer every time you try and get a lock, meaning you’ll effectively have no lock.

I came up with a work-around for this recently, that allows the locking of any value type. The core part to the solution is using a dictionary to map the value type to a reference type that can be locked. The solution is complicated somewhat by some extra logic that removes an object from the dictionary once no more locks are held against it.

The usage of the class is simple, and somewhat similar to the lock statement. The GetLock uses the first parameter as a “grouping” and the second parameter as the key to lock against. The grouping is necessary because it would be fairly easy to run into a scenario where the same value type is locked against in two unrelated blocks of code, blocking unnecessarily.

using (Locker&amp;amp;lt;int&amp;amp;gt;.GetLock(&amp;amp;quot;GroupName&amp;amp;quot;, 10))
{
    // Do something
}

And even though Locker only exposes one static method, GetLock, there’s quite a bit to it to make sure that any chase conditions are avoided, and there’s minimal wasted memory by removing unused locks from the dictionary (though this version doesn’t clean up an unused lock dictionary, meaning that using lots of groups would never entirely free the memory. This is solvable, but I’ll leave it for you to fix)


    /// <summary>
    /// Provides functionality to allow locking on value types
    /// </summary>
    public sealed class Locker<T> : IDisposable
    {
        #region Private Static Fields

        private static Dictionary<string, Dictionary<T, Locker<T>>> _lockDictionaries
            = new Dictionary<string, Dictionary<T, Locker<T>>>();

        #endregion

        #region Private Fields

        private int _lockCount;
        private bool _isLocked;
        private bool _isReleased;

        #endregion

        #region Private Constructor

        private Locker() { }

        #endregion

        #region Private Methods

        private bool Lock()
        {
            Interlocked.Increment(ref _lockCount);
            Monitor.Enter(this);
            // This lock has already been 'released', don't use it
            if (_isReleased)
            {
                Monitor.Exit(this);
                return false;
            }
            _isLocked = true;
            return true;
        }

        private void Unlock()
        {
            if (_isLocked)
            {
                var lockCount = Interlocked.Decrement(ref _lockCount);
                if (lockCount == 0)
                {
                    // The _lockCount is 0, we can now mark it as released
                    // and rase the AllLocksReleased event
                    _isReleased = true;
                    OnAllLocksReleased();
                }
                _isLocked = false;
                Monitor.Exit(this);
            }
        }

        #endregion

        #region AllLocksReleased Event

        private event EventHandler AllLocksReleased;

        private void OnAllLocksReleased()
        {
            if (AllLocksReleased != null)
                AllLocksReleased(this, EventArgs.Empty);
        }

        #endregion

        #region IDisposable Members

        public void Dispose()
        {
            Unlock();
        }

        #endregion

        #region Public Static Methods

        /// <summary>
        /// Aquires a lock for the given lockKey. IDisposable.Dispose() must be called to release the lock.
        /// </summary>
        /// <param name="groupName"></param>
        /// <param name="lockKey"></param>
        public static IDisposable GetLock(string groupName, T lockKey)
        {
            var lockDictionary = GetLockDictionary(groupName);

            Locker<T> lockObject;
            do
            {
                lockObject = null;
                if (!lockDictionary.TryGetValue(lockKey, out lockObject))
                {
                    lock (_lockDictionaries)
                    {
                        if (!lockDictionary.TryGetValue(lockKey, out lockObject))
                        {
                            // The lockDictionary dosn't have the key we're looking for, create a new instance
                            lockObject = new Locker<T>();
                            // Make sure the instance is released once all the locks are released
                            lockObject.AllLocksReleased += (o, e) => lockDictionary.Remove(lockKey);
                            lockDictionary.Add(lockKey, lockObject);
                        }
                    }
                }
            }
            while (!lockObject.Lock());
            // Continue looping until we acquire an unreleased lock

            return lockObject;
        }

        #endregion

        #region Private Static Methods

        /// <summary>
        /// Get's a lock dictionary for the given name
        /// </summary>
        /// <param name="name">The name of the dictionary to get.</param>
        private static Dictionary<T, Locker<T>> GetLockDictionary(string name)
        {
            Dictionary<T, Locker<T>> lockDictionary;
            if(!_lockDictionaries.TryGetValue(name, out lockDictionary))
            {
                lock(_lockDictionaries)
                {
                    if (!_lockDictionaries.TryGetValue(name, out lockDictionary))
                    {
                        lockDictionary = new Dictionary<T, Locker<T>>();
                        _lockDictionaries.Add(name, lockDictionary);
                    }
                }
            }
            return lockDictionary;
        }

        #endregion

    }

This code is provided As Is with no warranty expressed or implied.

Bookmark and Share

More thoughts on Lazy

Something that I missed when I mentioned my thoughts on an implementation of Lazy<T>, was that Microsoft was already a couple of steps ahead of me, and will include their own version in .NET 4.0, the MSDN documentation is here.

Their approach is slightly different to mine. Something I tried to do with my implementation was allow you to treat the Lazy<T> as the same type as the generic parameter, by adding the two implicit conversion operators and overriding the equals and hash methods. Microsoft has gone for a slightly different approach by making it immutable, and requiring you call the .Value property to get at the data.

It’d be interesting to hear why Microsoft went for this approach, but I can only guess they felt it was important to see that you’re dealing with an Lazy<T>, I prefer the approach closer to Nullable<T>, where the getting of the value is partially abstracted away.

There’s a couple more differences to mine, including optional thread safety, serialization and a better debugging experience with various debugger attributes, which I’d definitely do in my implementation next time around. Though does the optional thread safety really provide that much of a benefit?

Moving forward, I think there’s value in having this be a first level language construct, much like Nullable is, wouldn’t it be awesome to have:

    int~ fileCount = Directory.GetFiles(".\\").Length;

Compile into this?

    Lazy<int> fileCount = new Lazy<int>(() => Directory.GetFiles(".\\").Length);
Bookmark and Share

System.BadImageFormatException

Having recently started developing in Vista 64bit, this is an exception that I’ve bumped my head against a couple of times.

System.BadImageFormatException
“An attempt was made to load a program with an incorrect format. (Exception from HRESULT: 0×8007000B)”

If you’re in a 64bit environment, your solution is targeting “Any CPU” and you try to link to a 32bit library you’ll get this exception at runtime. Note that this doesn’t apply to just .NET libraries, if you’re linking to a native library you’ll get this exception too.

There’s an easy way to prove for certain that this is your issue by changing the the platform your targeting to x86 (you might need to use configuration manager to add the x86 solution platform).

Bookmark and Share

Dynamically generating an interface implementation at runtime

As part of some work to solve some problems I was experiencing with unclosed connections in WCF, I decided that on all calls to a method on a WCF interface, the channel should be closed immediately after use.

With the channels being generated by a ChannelFactory, I decided it would be best to write an implementation of the interface that simply re-implemented all the interfaces methods, with a using statement to close the channel, effectively creating a method like the following for every call.

public void SomeRemoteMethod()
{
    var channel = GetChannel();
    using((IDisposable)channel)
    {
        channel.SomeRemoteMethod();
    }
}

While that solved my problem, I did feel like I was introducing a lot of redundancy into the code as there where a dozen methods that needed implementing.

Also, that particular implementation added an issue where if the channel faulted, the call to the Dispose() method would result in another error being thrown, obscuring the initial exception.

Having recently gained some experience in dynamically generating classes in C#, I decided the best solution would be to dynamically generate a class that implemented the interface, and generated the same code as above:

    public static class InterfaceWrapper
    {
        #region Private Fields

        private static IDictionary<string, ModuleBuilder> _builders = new Dictionary<string, ModuleBuilder>();
        private static IDictionary<Type, Type> _types = new Dictionary<Type, Type>();
        private static object _lockObject = new object();

        #endregion

        #region Public Methods

        /// <summary>
        /// Creates an interface that matches the interface defined by <typeparamref name="T"/>
        /// </summary>
        public static T CreateInterface<T>(Func<T> getter, Type wrapperType)
        {
            return (T)CreateInterfaceInstance<T>(getter, wrapperType);
        }

        // Note that calling this method will cause any further
        // attempts to generate an interface to fail
        public static void Save()
        {
            foreach (var builder in _builders.Select(b => b.Value))
            {
                var ass = (AssemblyBuilder)builder.Assembly;
                try
                {
                    ass.Save(ass.GetName().Name + ".dll");
                }
                catch { }
            }
        }

        #endregion

        #region Private Methods 

        private static T CreateInterfaceInstance<T>(Func<T> getter, Type wrapperType)
        {
            var destType = GenerateInterfaceType(getter, wrapperType);

            return (T)Activator.CreateInstance(destType);
        }

        private static Type GenerateInterfaceType<T>(Func<T> getter, Type wrapperType)
        {
            #region Cache Fetch

            var sourceType = typeof(T);

            Type newType;
            if (_types.TryGetValue(sourceType, out newType))
                return newType;

            // Make sure the same interface isn't implemented twice
            lock (_lockObject)
            {
                if (_types.TryGetValue(sourceType, out newType))
                    return newType;

            #endregion

                #region Validation

                if (!sourceType.IsInterface)
                    throw new ArgumentException("Type T is not an interface", "T");

                if (!wrapperType.GetInterfaces().Contains(typeof(IDisposable)))
                    throw new ArgumentException("Type must implement IDisposable.", "wrapperType");

                var wrapperTypeConstructor = wrapperType.GetConstructor(new[] { typeof(object) });
                if (wrapperTypeConstructor == null)
                    throw new ArgumentException("Type must have a single constructor that takes a single object parameter.", "wrapperType");

                var getterMethod = getter.Method;
                if ((getterMethod.Attributes & MethodAttributes.Public) != MethodAttributes.Public)
                    throw new ArgumentException("Method must be public.", "getter");

                #endregion

                #region Module and Assembly Creation

                var orginalAssemblyName = sourceType.Assembly.GetName().Name;

                ModuleBuilder moduleBuilder;
                if (!_builders.TryGetValue(orginalAssemblyName, out moduleBuilder))
                {
                    var newAssemblyName = new AssemblyName(Guid.NewGuid() + "." + orginalAssemblyName);

                    var dynamicAssembly = AppDomain.CurrentDomain.DefineDynamicAssembly(
                        newAssemblyName,
                        System.Reflection.Emit.AssemblyBuilderAccess.RunAndSave);

                    moduleBuilder = dynamicAssembly.DefineDynamicModule(
                        newAssemblyName.Name,
                        newAssemblyName + ".dll");

                    _builders.Add(orginalAssemblyName, moduleBuilder);
                }

                var assemblyName = moduleBuilder.Assembly.GetName();

                #endregion

                #region Create the TypeBuilder

                var typeBuilder = moduleBuilder.DefineType(
                    sourceType.FullName,
                    TypeAttributes.Public | TypeAttributes.Class,
                    typeof(object),
                    new[] { sourceType });

                #endregion

                #region Enumerate interface inheritance hierarchy

                var interfaces = new List<Type>();
                IEnumerable<Type> subList;

                subList = new[] { sourceType };

                while (subList.Count() != 0)
                {
                    interfaces.AddRange(subList);
                    subList = subList.SelectMany(i => i.GetInterfaces());
                }

                interfaces = interfaces.Distinct().ToList();

                #endregion

                #region Create the methods

                foreach (var method in interfaces.SelectMany(i => i.GetMethods()))
                {
                    // Define the method based on the interfaces definition
                    var newMethod = typeBuilder.DefineMethod(
                        method.Name,
                        method.Attributes ^ MethodAttributes.Abstract,
                        method.CallingConvention,
                        method.ReturnType,
                        method.ReturnParameter.GetRequiredCustomModifiers(),
                        method.ReturnParameter.GetOptionalCustomModifiers(),
                        method.GetParameters().Select(p => p.ParameterType).ToArray(),
                        method.GetParameters().Select(p => p.GetRequiredCustomModifiers()).ToArray(),
                        method.GetParameters().Select(p => p.GetOptionalCustomModifiers()).ToArray()
                        );

                    // Check to see if we have a return type
                    bool hasReturnValue = method.ReturnType != typeof(void);

                    var methodBody = newMethod.GetILGenerator();

                    // sourceType var0;
                    // wrapperType var1;
                    methodBody.DeclareLocal(sourceType);
                    methodBody.DeclareLocal(wrapperType);

                    // returnType var2;
                    if (hasReturnValue)
                        methodBody.DeclareLocal(method.ReturnType);

                    // var0 = getter();
                    methodBody.Emit(OpCodes.Call, getterMethod);
                    methodBody.Emit(OpCodes.Stloc_0);

                    // var1 = new wrapperType(var0);
                    methodBody.Emit(OpCodes.Ldloc_0);
                    methodBody.Emit(OpCodes.Newobj, wrapperTypeConstructor);
                    methodBody.Emit(OpCodes.Stloc_1);

                    // using (var1) {
                    methodBody.BeginExceptionBlock();

                    // (load the object to call the method on)
                    methodBody.Emit(OpCodes.Ldloc_0);

                    // (load any parameters)
                    for (int i = 1; i <= method.GetParameters().Length; ++i)
                        methodBody.Emit(OpCodes.Ldarg, i);

                    // var2 = var0.method(...);
                    methodBody.Emit(OpCodes.Callvirt, method);

                    if (hasReturnValue)
                        methodBody.Emit(OpCodes.Stloc_2);

                    // } (end using)
                    methodBody.BeginFinallyBlock();

                    methodBody.Emit(OpCodes.Ldloc_1);
                    methodBody.Emit(OpCodes.Callvirt, typeof(IDisposable).GetMethod("Dispose"));

                    methodBody.EndExceptionBlock();

                    // return var2;
                    if (hasReturnValue)
                        methodBody.Emit(OpCodes.Ldloc_2);

                    // return;
                    methodBody.Emit(OpCodes.Ret);
                }

                #endregion

                #region Create and return the defined type

                newType = typeBuilder.CreateType();

                _types.Add(sourceType, newType);

                return newType;

            }
                #endregion
        }

        #endregion
    }

Then, using the following class for the wrapperType parameter, I solved the disposing a faulted channel problem also:

    public class ChannelDisposer : IDisposable
    {
        private object _channel;

        public ChannelDisposer(object channel)
        {
            if (!(channel is IChannel))
                throw new ArgumentException("Argument dosn't implement IChannel", "channel");

            if (!(channel is IDisposable))
                throw new ArgumentException("Argument dosn't implement IDisposable", "channel");

            _channel = channel;
        }

        #region IDisposable Members

        public void Dispose()
        {
            if (((IChannel)_channel).State != CommunicationState.Faulted)
                ((IDisposable)_channel).Dispose();
        }

        #endregion
    }

Then finally I can pull it all together with a single call:

IService service = InterfaceWrapper.CreateInterface<IService>(CreateServiceInstance, typeof(ChannelDisposer));

This code is provided As Is with no warranty expressed or implied.

Bookmark and Share

Lazy evaluation of variables in C#

In an attempt to revitalize this blog, I’m going to write a few post on random bits of code that I’ve found useful recently.

The first sample is Lazy<T>. This simple class allows you to delay the initialization of a variable till its first use. This can come in handy if you have a method with many code paths and you’d like to initialize all variables at the start of the method without the overhead of initializing unnecessarily.

Here’s a usage example:

var fileCount = new Lazy<int>(() => Directory.GetFiles(".\\").Length);

And the class:

        public class Lazy<T>
        {
            private bool _hasValue;
            private T _value;
            private Func<T> _getter;

            public Lazy(Func<T> getter)
            {
                _getter = getter;
            }

            public T Value
            {
                get
                {
                    if (!_hasValue)
                    {
                        lock (this)
                        {
                            if (!_hasValue)
                            {
                                _value = _getter();
                                _hasValue = true;
                            }
                        }
                    }
                    return _value;
                }
            }

            public override bool Equals(object other)
            {
                if (Value == null)
                {
                    return (other == null);
                }
                if (other == null)
                {
                    return false;
                }
                return Value.Equals(other);
            }

            public override int GetHashCode()
            {
                if (Value == null)
                {
                    return 0;
                }
                return Value.GetHashCode();
            }

            public override string ToString()
            {
                if (Value == null)
                {
                    return "";
                }
                return Value.ToString();
            }

            public static implicit operator Lazy<T>(T value)
            {
                return new Lazy<T>(() => value);
            }

            public static implicit operator T(Lazy<T> value)
            {
                return value.Value;
            }
        }
Bookmark and Share

How to use Debug.Write and Trace.Write across app domain boundaries

If you’ve ever written an application that uses multiple application domains you may have noticed that calls to Debug.Write or Trace.Write in new application domains get lost, especially if you’ve add the TraceListener in code (e.g. “Debug.Listeners.Add(new ConsoleTraceListener());”).

Fortunately this is reasonably easy to solve with just two classes, one to handle the Debug.Write events in the child domain and another to handle the communication of messages between domains. I’m going to use a TraceListener implementation that I originally wrote to help with the writing of Debug messages to a TextBox in a WPF application, I call in the DelegateTraceListener, and it looks like this:

    private class DelegateTraceListener : TraceListener
    {
        private Action<string> _write;

        public DelegateTraceListener(Action<string> write)
        {
            _write = write;
        }

        public override void Write(string message)
        {
            _write(message);
        }

        public override void WriteLine(string message)
        {
            Write(message + Environment.NewLine);
        }
    }

Which can be easily used in my aforementioned WPF scenario like so:

    Debug.Listeners.Add(
        new DelegateTraceListener(
            message => textBox1.AppendText(message)));

The other class required to allow messages to cross between domains CrossDomainTraceHelper, which does a couple of things. Firstly it creates two instances of itself, one in the domain you specify and one in the current domain, secondly it uses the DelegateTraceListener to receive messages from the child domain, thirdly it pipes the messages from the child domain instance to the local domain instance, lastly it writes the messages to the Debug object.

    public class CrossDomainTraceHelper : MarshalByRefObject
    {
        private CrossDomainTraceHelper _parentDomain;

        private CrossDomainTraceHelper()
        {
        }

        public static void StartListening(AppDomain domain)
        {
            var listenerType = typeof(CrossDomainTraceHelper);

            // Create a remote instance
            var remoteHelper =
                (CrossDomainTraceHelper)domain.CreateInstanceAndUnwrap(
                    listenerType.Assembly.FullName,
                    listenerType.FullName);

            // Create a local instance
            var localHelper = new CrossDomainTraceHelper();

            // Register the local helper in the remote domain
            remoteHelper.Register(localHelper);
        }

        private void Register(CrossDomainTraceHelper parentDomain)
        {
            // Store the parent domain to pass messages to later
            _parentDomain = parentDomain;

            // Create and register the delegate trace listener
            var listener = new DelegateTraceListener(Write);

            Debug.Listeners.Add(listener);
        }

        private void Write(string message)
        {
            // Send the message to the parent domain
            _parentDomain.RemoteWrite(message);
        }

        private void RemoteWrite(string message)
        {
            Debug.Write(message);
        }
    }

Now you can start listening for Debug messages in the remote domain with a single line:

    CrossDomainTraceHelper.StartListening(domain);

Phil

Bookmark and Share

Advanced exception handling in ASP.NET

Logging exceptions is crucial in ASP.NET applications. If you don’t have logging, who knows what could be going wrong with your application. Your users could be getting hundreds of errors without you even knowing if you don’t have popper logging set up in your application.

Most sites get the basics right for logging, but there are some circumstances which can easily be missed. For example, I worked on a site a couple of years ago, and we hadn’t quite got our error logging right. We also had an issue that during deploy time, thousands of error where being generated because we hadn’t configured the request queue limit correctly and because the app took a while to spin up, the queue would fill up and the site would error. We had no idea, and it wasn’t till we fixed the logging like I’ll describe here that we realized and where able to fix it.

The first place you’ll want error logging is in your Global.asax in the Application_OnError method. This method should be included when you create the Global.asax file. This method is called when any exception isn’t handled specifically within the code bubbles to the top of the stack. This the easiest way to start your logging, you just need to fill in the method with your error logging code.

Global.asax

namespace WebApplication
{
    public class Global : System.Web.HttpApplication
    {
        protected void Application_Error(object sender, EventArgs e)
        {
            Exception ex = Server.GetLastError();
            // Error handling code goes here
        }
    }
}

That works fine assuming two things: Firstly, your error logging code is correct, secondly, your applications DLLs are able to load correctly. What if they can’t? Then we take it to the next level of logging, configuring Web.Config to redirect to a page on error and than doing separate logging there.

At this level we’ll lose a little detail. Redirecting the error page loses the exception, but at least we know an error’s happening. We can also tell what page the error happened on and what HTTP status code was given out in the response. You’ll need to create a new file which handles the logging in it (in the Page_Load method for example,) though in order to get both file name and status code you’ll either need multiple error logging files or a rewrite rule using something like ISAPI_rewrite. The reason is that if you choose to include the status code in the query string the internal logic won’t automatically append the url to the query string, so the status code has to be part of the file name.

Web.Config

<?xml version="1.0"?>
<configuration>
  <system.web>
    <customErrors defaultRedirect="/ErrorUnkown.aspx">
      <error statusCode="404"  redirect="/Error404.aspx"/>
      <error statusCode="500"  redirect="/Error500.aspx"/>
      <!-- Etc. -->
    </customErrors>
  </system.web>
</configuration>

The previous method for logging while fail in a couple of scenarios. If the .NET run time fails to spin up at all due to configuration issues with IIS, or the Web.Config file becomes corrupt are just a couple of examples. The only way you can deal with this is by configuring IIS its self to deal with the issue. You can configure IIS to redirect the user to a different file if an error’s raised, since we’re assuming that the current website can’t be accessed we need to come up with something other than .NET to log the error. My solution was to use a Classic ASP file to log the error, because that should still work even if .NET is failing.

The first think you’ll need to do is create the Classic ASP file which logs errors to the correct location, which should be straight forward enough. Then you’ll need to configure IIS. In IIS 7 this is done through the error pages section, and once configured should look something like this:

IIS 7 Error Pages
IIS 7 Error Pages

I don’t have a sample screen shot for what it’ll look like in IIS 5/6, but Microsoft has provided a tutorial.

With all these measures in place, you should have a complete view of all errors you are generating on your site. Though you should also consider manually logging an error when you’ve caught the exception already and don’t want to display anything to the users.

You should also consider how you log your errors. You should try and log as much information as possible (cookies, query-string, form and all the headers in the request for example,) ideally into a place where it’ll be easy to generate reports from, somewhere like a SQL database is ideal.

Phil

Bookmark and Share