Guide to Improving Code Performance in .NET: Part II



In this article, we will look into handling errors in an optimistic way. Handling of errors is quite common task in any kind of programming language. Most of the modern languages like C++, C# uses similar kind of exception handling constructs. We will see how to handle exceptions without any performance impact on the application by examples. I will be using VS 2008 with C# as language for all the samples.

Exception Handling helps us to create robust and secure applications at a performance loss. So, we need to be careful in handling the exceptions. Always remember that throwing and catching exceptions is of high cost. So use exceptions to handle unexpected scenarios. Don't use exceptions for handling invalid data or to control the flow of code. Use finally block to release resources irrespective of error occurrence. Handle all kinds of invalid data using validations instead of exceptions. Try to handle all kind of exceptions for a better logging. Don't handle all kind of exceptions using single generic catch block. Don't throw/re-throw exceptions unnecessarily. Throw the exceptions that you can handle. Use performance counters to estimate the impact of exceptions on application performance in terms of number of exceptions thrown/caught.

Use "using" block to release the resources immediately without the need of try/finally block. Let's touch all the above scenarios with an example. Create a console application named as ExceptionHndPractice.

  • Don't use exception handling to control the flow of execution as shown below:

    Instead of


    //Get Employee Details.

    if (GetEmployee(empID) == null)
        throw new Exception("No Employee");

    Use

    //Get Employee Details.

    if (GetEmployee(empID) == null)
        return null;

     
  • Use validations to handle invalid data as shown below:

    Instead of

    try

    {
        //InValid Date.
        DateTime dt = DateTime.Parse(Console.ReadLine());
    }
    catch (Exception ex)
    {
        Console.WriteLine(ex.Message);
    }

    Use

    //InValid Date.

    DateTime
    dt;
    if(!DateTime.TryParse(Console.ReadLine(), out dt))
    {
        Console.WriteLine("Not a valid date.");
    }
     
  • Use of exception specific catch blocks instead of generic catch block as shown below:

    try

    {
    }
    catch
    (ArgumentException aex)
    {
        Console.WriteLine(aex.Message);
    }
    catch
    (InvalidCastException iex)
    {
        Console.WriteLine(iex.Message);
    }
    catch
    (Exception ex)
    {
        Console.WriteLine(ex.Message);
    }


    Always have generic exception handler at the end to handle unexpected exception types. Log the exception information to a data source or file for diagnosing the code.
     
  • Don't throw/re-throw the exceptions unnecessarily as shown below:

    try

    {
    }
    catch
    (ArgumentException aex)
    {
        throw aex;
    }

Throwing an exception is almost same as creating a new exception. Throw an exception, if u really wants to log more diagnostic details.
  • Rollback the changes done before throwing an exception to avoid side effects.
  • Arrange catch blocks to handle most specific to least specific exceptions.
  • Use Performance counters to understand the impact of exceptions on application.
  • Use empty throw when catching and re-throwing an exception for preserving call stack pointed to exact error location.

I am ending up the things here. I hope this article will be helpful for all.


Similar Articles