Category: ASP.NET


If the performance of a .NET application is effected during the peak load times, it is the end users who will be effected ultimately. This is the reason why distributed caching has become a hot cake for the .NET developers. it not only boost the performance of the application during peak load times, but it also provides scalability and reliability. There are numbers of third party distributed cache provider are available which are doing very good job, NCache and App Fabric being the two most famous ones.

NCache Features that App Fabric does not have

Below is a list of features which make NCache the premier distributed cache provider. Continue reading “NCache Features that App Fabric does not have” »

NCache Distributed In-memory Object Cache

Introduction

In my last post I discussed how you can setup Windows AppFabric Caching and use it from ASP.NET MVC.

AppFabric isn’t the only tool out there that provides you with a distributed in-memory object cache. NCache from Alachisoft is another excellent product which can solve your caching issues.

Let’s see it in action…

 

Table Of Contents

Installation

Lets first install NCache. At the time of writing, version 3.8 had just been launched. You can download the professional or enterprise edition on the following page: Continue reading “NCache Distributed In-memory Object Cache” »

Windows Server AppFabric Caching

Introduction

For those of you who haven’t heard about AppFabric yet, check out the Windows Server AppFabric Learning Center on MSDN. The first version is out now and can be downloaded here.

One key functionality of AppFabric that caught my attention was its caching feature also known as Velocity (Project Code Name). To quote MSDN:

For Web applications, AppFabric provides caching capabilities to provide high-speed access, scale, and high availability to application data.

Sounds interesting, especially as I am building a web application which is going to be hosted in a web farm. Instead of using ASP.NET’s built-in caching option, which is tied to a single AppDomain and thus one web server, I can opt to use a cache powered by AppFabric which is shared across web servers.

Let’s see it in action…

 

Table Of Contents

Installation

Lets first install AppFabric. Download the most appropriate Windows Server AppFabric version for you on the following page: Continue reading “Windows Server AppFabric Caching” »

A very good book by the authors that I admire and appreciate mentioned the use of a class called SQLAsyncResult to access data asynchronously using ADO.NET 2.0 via the callback approach. My attempt to try out an example failed as I couldn’t find the SQLAsyncResult class, not in the namespace, not in the MSDN library. However, I did find a post on ASP.NET forum about a dev’s unsuccessful hunt for this class and an MVP answering that it might be a type in the example.
The reason I’m mentioning it at the start of this post is that, if any one developer finds this class, I would really appetite you leaving a comment.
Now, back to the Callback approach …

This post is in continuation to my previous post about Asynchronous data access using ADO.NET however, that post need not be referred if you are interesting in the callback only.
In this approach we leverage .NET infrastructure relating to threading, AsyncCallback delegate, the AsyncResult class and the IAsyncResult interface.
The approach is accomplished by:

  • Creating a call back method which will process the data (essentially call the end invoke command) which accepts the IAsyncResult
  • Creating an AsyncCallback delegate for the callback methods created &
  • Passing the delegate along with the command object in the begin invoke command.

Here’s a simple implementation of the call back approach:
The model class to load data:

public class Customer {

    public Customer() {
    }

    public Customer(SqlDataReader reader) {

        CustomerID = reader["CustomerID"].ToString();
        CompanyName = reader["CompanyName"] == null ? string.Empty : reader["CompanyName"].ToString();
        ContactName = reader["ContactName"] == null ? string.Empty : reader["ContactName"].ToString();
        Phone = reader["Phone"] == null ? string.Empty : reader["Phone"].ToString();
    }

    public string CustomerID { get; set; }
    public string CompanyName { get; set; }
    public string ContactName { get; set; }
    public string Phone { get; set; }

}

Here’s the data access class that fetches customer asynchronously using the callback approach:

public class CustomerDB {

    /// <summary>
    /// This variable keeps the track of number of asynchronous calls
    /// </summary>
    private static int counter = 0;

    /// <summary>
    /// Class member to store the result.
    /// </summary>
    private List<Customer> _customers = new List<Customer>();

    /// <summary>
    /// This is the main method that needs to be called from other application layer to get Customers.
    /// </summary>
    /// <returns></returns>
    public List<Customer> GetCustomers() {

        //Initiate Connection
        SqlConnection con = new SqlConnection();
        con.ConnectionString = ConfigurationManager.ConnectionStrings["NorthwindConnectionString"].ConnectionString;

        //Initiate Command
        SqlCommand cmd = con.CreateCommand();
        cmd.CommandText = "SELECT top 10 * FROM [Customers]";
        cmd.CommandType = CommandType.Text;

        try {

            con.Open();

            // create AsyncCallback delegate
            AsyncCallback callback = new AsyncCallback(RetrieveDataCallback);

            cmd.BeginExecuteReader(callback, cmd, CommandBehavior.CloseConnection);

            //Wait until the call is complete
            while (counter < 1) {
            }

        }
        catch {
            //Log error
        }

        return _customers;

    }

    /// <summary>
    /// The callback method to retrieve data.
    /// </summary>
    /// <param name="result"></param>
    private void RetrieveDataCallback(IAsyncResult result) {

        SqlDataReader dr = null;

        try {
            SqlCommand command = (SqlCommand)result.AsyncState;
            Customer customer = null;

            dr = command.EndExecuteReader(result);

            while (dr.Read()) {

                customer = new Customer(dr);
                _customers.Add(customer);
            }
        }
        catch {
            //Log error
        }
        finally {

            try {
                if (!dr.IsClosed) {
                    dr.Close();
                }
            }
            catch { } //Suppress any exceptions here

            //Increment value to notify that the call is complete.
            Interlocked.Increment(ref counter);

        }
    }
}

Let’s rewrite this code to make multiple calls to different databases using the same customer model class. To make sure that the data access is thread safe we need to add a static object. This static object needs to be locked every time a thread completes and attempts to update the Customers list. Here’s the new CustomerDB class:

public class CustomerDB {

    /// <summary>
    /// static object for thread safety.
    /// </summary>
    static object lockObject = new object();

    /// <summary>
    /// This variable keeps the track of number of asynchronous calls
    /// </summary>
    private static int counter = 0;

    /// <summary>
    /// Class member to store the result.
    /// </summary>
    private List<Customer> _customers = new List<Customer>();

    /// <summary>
    /// This is the main method that needs to be called from other application layer to get Customers.
    /// </summary>
    /// <returns></returns>
    public List<Customer> GetCustomers() {

        //Initiate Connection
        SqlConnection con1 = new SqlConnection();
        con1.ConnectionString = ConfigurationManager.ConnectionStrings["NorthwindConnectionString"].ConnectionString;
        SqlConnection con2 = new SqlConnection();
        con1.ConnectionString = ConfigurationManager.ConnectionStrings["SouthwindConnectionString"].ConnectionString;
        SqlConnection con3 = new SqlConnection();
        con1.ConnectionString = ConfigurationManager.ConnectionStrings["EastwindConnectionString"].ConnectionString;

        //Initiate Command
        SqlCommand cmd1 = con1.CreateCommand();
        SqlCommand cmd2 = con2.CreateCommand();
        SqlCommand cmd3 = con3.CreateCommand();

        //The table structures are same in my case.
        //In case of different table structures include logic in the call back method
        //or Customer constructor to DB specific load.
        cmd1.CommandText = "SELECT top 10 * FROM [Customers]";
        cmd1.CommandType = CommandType.Text;
        cmd2.CommandText = "SELECT top 10 * FROM [Customers]";
        cmd2.CommandType = CommandType.Text;
        cmd3.CommandText = "SELECT top 10 * FROM [Customers]";
        cmd3.CommandType = CommandType.Text;

        try {

            con1.Open();
            con2.Open();
            con3.Open();

            // create AsyncCallback delegate
            AsyncCallback callback1 = new AsyncCallback(RetrieveDataCallback);
            AsyncCallback callback2 = new AsyncCallback(RetrieveDataCallback);
            AsyncCallback callback3 = new AsyncCallback(RetrieveDataCallback);

            cmd1.BeginExecuteReader(callback1, cmd1, CommandBehavior.CloseConnection);
            cmd2.BeginExecuteReader(callback2, cmd2, CommandBehavior.CloseConnection);
            cmd3.BeginExecuteReader(callback3, cmd3, CommandBehavior.CloseConnection);

            //Wait until all the call are complete
            while (counter < 3) {
            }

        }
        catch {
            //Log error
        }

        return _customers;

    }

    /// <summary>
    /// The callback method to retrieve data.
    /// </summary>
    /// <param name="result"></param>
    private void RetrieveDataCallback(IAsyncResult result) {

        SqlDataReader dr = null;

        try {
            SqlCommand command = (SqlCommand)result.AsyncState;
            Customer customer = null;

            dr = command.EndExecuteReader(result);

            while (dr.Read()) {

                customer = new Customer(dr);

                // lock the static object when data is loaded
                lock (lockObject) {

                    _customers.Add(customer);
                }

            }
        }
        catch {
            //Log error
        }
        finally {

            try {
                if (!dr.IsClosed) {
                    dr.Close();
                }
            }
            catch { } //Suppress any exceptions here

            //Increment value to notify that the call is complete.
            Interlocked.Increment(ref counter);

        }
    }
}

Asynchronous Data Access using ADO.NET

ADO.NET 2.0 enabled the infrastructure required for accessing data in asynchronous mode.

Three standard approaches available to achieve this are:

  • The Poll approach,
  • The Wait approach &
  • The Callback approach.

The approach to choose will depend upon the scenario. Between the Poll and Wait approaches, the Wait approach is better. It provides a great deal of flexibility and efficiency with a bit more complexity than the other. The Callback approach is extreme and runs more in parallel to the multi threading and other asynchronous process paradigm. It helps creating asynchronous/multithreaded data access mechanism even outside SQL/ADO.NET. Drivers and Frameworks which do not come with asynchronous infrastructure.

To enable asynchronous data access, we would need to add “Asynchronous Processing=true;” in the connection string.

The asynchronous access is triggered by the command methods prefixed by “Begin” and the result is retrieved through their “End” counterparts as below:

Synchronous Methods
Asynchronous methods
Start process returns IAsunchResult End process returns data
ExecuteNonQuery BeginExecuteNonQuery EndExecuteNonQuery
ExecuteReader BeginExecuteReader EndExecuteReader
ExecuteXmlReader BeginExecuteXmlReader EndExecuteXmlReader

Each of these asynchronous execution methods return  IAsyncResult. The IAsyncResult allows us to control and read into the asynchronous call with it properties – IsCompleted, AsyncState,  CompletedSynchronously & AsyncWaitHandle. The AsyncWaitHandle property returns the WaitHandle object.

The WaitHandle is an abstract class which provides a handle to the asynchronous execution. It exposed methods such as WaitOne(), WaitAny() and WaitAll() notifying the status of the execution. To process more than one databases commands, we can simply create an array containing wait handles for each process and wait till the WaitAll() or WaitAny() responds.

AsyncCallback is a delegate, used to specify which method to be called once the Asynchronous process is over.

For the next few examples we’ll be using the following modal and it’s constructor. Passing the reader is not the best way to initiate a class in many scenarios but it works for our examples.

public class Customer {

    public Customer() {
    }

    public Customer(SqlDataReader reader) {

        CustomerID = reader["CustomerID"].ToString();
        CompanyName = reader["CompanyName"] == null ? string.Empty : reader["CompanyName"].ToString();
        ContactName = reader["ContactName"] == null ? string.Empty : reader["ContactName"].ToString();
        Phone = reader["Phone"] == null ? string.Empty : reader["Phone"].ToString();
    }

    public string CustomerID { get; set; }
    public string CompanyName { get; set; }
    public string ContactName { get; set; }
    public string Phone { get; set; }

}

The Poll Approach:

In the poll approach, we make a call to the database, executing the required command and keep polling the status or the command to check if the execution is complete. Here’s the method that does just that:

public List<Customer> GetAllCustomers() {

    List<Customer> customers = new List<Customer>();
    IAsyncResult asyncResult = null;;
    SqlDataReader sqlReader = null;

    SqlConnection sqlConnection = new SqlConnection();
    sqlConnection.ConnectionString = ConfigurationManager.ConnectionStrings["NorthwindConnectionString"].ConnectionString;
    SqlCommand sqlCommand = sqlConnection.CreateCommand();
    sqlCommand.CommandText = "SELECT top 10 * FROM [Customers]";
    sqlCommand.CommandType = CommandType.Text;

    try{
        sqlConnection.Open();

        //Start Async process
        asyncResult = sqlCommand.BeginExecuteReader();

        while (!asyncResult.IsCompleted) {
            //Wait till Async process is executing
            Thread.Sleep(10);
        }

        //Retrieve result from the Async process
        sqlReader = sqlCommand.EndExecuteReader(asyncResult);

        while (sqlReader.Read()) {
            customers.Add(new Customer(sqlReader));
        }

        sqlConnection.Close();
    }
    catch(Exception ex){

    }

    return customers;

}

The Wait Approach

Using this approach we can start multiple asynchronous processes and wait till they are complete. The real benefit of  the wait process doesn’t come into the picture unless you have to make multiple database calls in the same or make calls to different databases to get the same entity.

Imagine we need to fetch customers as well as employees using the following employee model

public class Employee {

    public Employee() { }

    public Employee(SqlDataReader reader) {

        EmployeeID = (int)reader["EmployeeID"];
        LastName = reader["LastName"] == null ? string.Empty : reader["LastName"].ToString();
        FirstName = reader["FirstName"] == null ? string.Empty : reader["FirstName"].ToString();
        Title = reader["Title"] == null ? string.Empty : reader["Title"].ToString();

    }

    public int EmployeeID { get; set; }
    public string LastName { get; set; }
    public string FirstName { get; set; }
    public string Title { get; set; }
}

In order to enable the connection to support multiple result sets, as in this case, we would need to set the MultipleActiveResultSets property of the connection string to true. To do that add “MultipleActiveResultSets = true;” in the connection string.

After those setting taken care of, we fire multiple commands using the wait approach:

List<Customer> customers = new List<Customer>();
    List<Employee> employees = new List<Employee>();

    SqlDataReader customerSqlReader = null;
    SqlDataReader employeeSqlReader = null;

    IAsyncResult customerAsyncResult = null;
    IAsyncResult employeeAsyncResult = null;
    WaitHandle[] waitHandles = new WaitHandle[2];

    SqlConnection sqlConnection = new SqlConnection();
    sqlConnection.ConnectionString = ConfigurationManager.ConnectionStrings["NorthwindConnectionString"].ConnectionString;

    SqlCommand customerSqlCommand = new SqlCommand();
    customerSqlCommand.Connection = sqlConnection;
    customerSqlCommand.CommandText = "SELECT top 10 * FROM [Customers]";
    customerSqlCommand.CommandType = CommandType.Text;

    SqlCommand employeeSqlCommand = new SqlCommand();
    employeeSqlCommand.Connection = sqlConnection;
    employeeSqlCommand.CommandText = "SELECT top 10 * FROM [Employees]";
    employeeSqlCommand.CommandType = CommandType.Text;

    try{
        sqlConnection.Open();

        //Start Async processes
        customerAsyncResult = customerSqlCommand.BeginExecuteReader();
        employeeAsyncResult = employeeSqlCommand.BeginExecuteReader();
        waitHandles[0] = customerAsyncResult.AsyncWaitHandle;
        waitHandles[1] = employeeAsyncResult.AsyncWaitHandle;

        WaitHandle.WaitAll(waitHandles);

        //Retrieve result from the Async process
        customerSqlReader = customerSqlCommand.EndExecuteReader(customerAsyncResult);
        while (customerSqlReader.Read()) {
            customers.Add(new Customer(customerSqlReader));
        }

        employeeSqlReader = employeeSqlCommand.EndExecuteReader(employeeAsyncResult);
        while (employeeSqlReader.Read()) {
            employees.Add(new Employee(employeeSqlReader));
        }

        sqlConnection.Close();
    }
    catch(Exception ex){

    }

In the above code snippet  we wait for all the database calls to complete before processing it. An improvement that can be made here is processing data as we receive it. To achieve that, we would have to use the WaitAny() instead of the WaitAll() method and running a loop for each execution. Here’s how:

List<Customer> customers = new List<Customer>();
    List<Employee> employees = new List<Employee>();

    SqlDataReader customerSqlReader = null;
    SqlDataReader employeeSqlReader = null;

    IAsyncResult customerAsyncResult = null;
    IAsyncResult employeeAsyncResult = null;
    WaitHandle[] waitHandles = new WaitHandle[2];

    SqlConnection sqlConnection = new SqlConnection();
    sqlConnection.ConnectionString = ConfigurationManager.ConnectionStrings["NorthwindConnectionString"].ConnectionString;

    SqlCommand customerSqlCommand = new SqlCommand();
    customerSqlCommand.Connection = sqlConnection;
    customerSqlCommand.CommandText = "SELECT top 10 * FROM [Customers]";
    customerSqlCommand.CommandType = CommandType.Text;

    SqlCommand employeeSqlCommand = new SqlCommand();
    employeeSqlCommand.Connection = sqlConnection;
    employeeSqlCommand.CommandText = "SELECT top 10 * FROM [Employees]";
    employeeSqlCommand.CommandType = CommandType.Text;

    try{
        sqlConnection.Open();

        //Start Async processes
        customerAsyncResult = customerSqlCommand.BeginExecuteReader();
        employeeAsyncResult = employeeSqlCommand.BeginExecuteReader();
        waitHandles[0] = customerAsyncResult.AsyncWaitHandle;
        waitHandles[1] = employeeAsyncResult.AsyncWaitHandle;

        for (int i = 0; i < 2; i++) {

            int waitHandleIndex = WaitHandle.WaitAny(waitHandles);

            switch (waitHandleIndex) {

                case 0:
                    customerSqlReader = customerSqlCommand.EndExecuteReader(customerAsyncResult);

                    while (customerSqlReader.Read()) {
                        customers.Add(new Customer(customerSqlReader));
                    }

                    break;

                case 1:
                    employeeSqlReader = employeeSqlCommand.EndExecuteReader(employeeAsyncResult);

                    while (employeeSqlReader.Read()) {
                        employees.Add(new Employee(employeeSqlReader));
                    }

                    break;
            }
        }

        sqlConnection.Close();
    }
    catch(Exception ex){

    }

The Callback approach:

This wait approach it great will give the best solution in all the practical scenarios that you will come across.  Please refer to the next blog post for the callback approach.

It has been an absolute exhausting work week. My eyes, wrists, and back are sore from too many hours of coding. Thankfully I get to relax much of the Memorial Day Weekend :) I hope you all enjoy the weekend, too.

This week a client sent me an Excel Spreadsheet that needed to populate several tables in a SQL Server Database. To know me knows I hate data entry of any kind and there was no chance I was entering the Excel data in manually.

Thankfully, we don’t have to. You can use the OleDb Managed Data Provider in the .NET Framework to read an Excel Spreadsheet using ADO.NET and C# just like you would with a database.

Shown below is a simple spreadsheet that lists a few cities ( Bradenton, Sarasota, and Tampa ) in Florida. Notice I have renamed the worksheet to Cities as opposed to the default of Sheet1. Also notice that the first row contains headers of the columns. These changes will impact the way we access the information as you will see in a moment.

David Hayden - Excel and ADO.NET

Excel Connection String for ADO.NET

You will first need a connection string to connect to the Excel Workbook, which would be the following:

 

string connectionString = @"Provider=Microsoft.Jet.OLEDB.4.0;
    Data Source=Book1.xls;Extended Properties=
    ""Excel 8.0;HDR=YES;""";

 

This says the spreadsheet is located in the current directory and called Book1.xls, and the first row is a header row containing the names of the columns.

Read Excel Spreadsheet using ADO.NET and DbDataReader

Once you have the connection string all normal ADO.NET coding applies. Here is some sample code that reads each row of the excel worksheet using DbDataReader. You don’t have to use the DbProviderFactory Classes. I thought I would show it just for kicks.

 

string connectionString = @"Provider=Microsoft.Jet.
    OLEDB.4.0;Data Source=Book1.xls;Extended
    Properties=""Excel 8.0;HDR=YES;""";

DbProviderFactory factory =
  DbProviderFactories.GetFactory("System.Data.OleDb");

using (DbConnection connection = factory.CreateConnection())
{
    connection.ConnectionString = connectionString;

    using (DbCommand command = connection.CreateCommand())
    {
        // Cities$ comes from the name of the worksheet
        command.CommandText = "SELECT ID,City,State
                                      FROM [Cities$]";

        connection.Open();

        using (DbDataReader dr = command.ExecuteReader())
        {
            while (dr.Read())
            {
                Debug.WriteLine(dr["ID"].ToString());
            }
        }
    }
}

 

Read Excel Spreadsheet using ADO.NET and DataSet

Here is another example of reading an Excel spreadsheet using ADO.NET and a DataSet.

 

string connectionString = @"Provider=Microsoft.Jet.
    OLEDB.4.0;Data Source=Book1.xls;Extended
    Properties=""Excel 8.0;HDR=YES;""";

DbProviderFactory factory =
   DbProviderFactories.GetFactory("System.Data.OleDb");

DbDataAdapter adapter = factory.CreateDataAdapter();

DbCommand selectCommand = factory.CreateCommand();
selectCommand.CommandText = "SELECT ID,City,State
                                     FROM [Cities$]";

DbConnection connection = factory.CreateConnection();
connection.ConnectionString = connectionString;

selectCommand.Connection = connection;

adapter.SelectCommand = selectCommand;

DataSet cities = new DataSet();

adapter.Fill(cities);

gridEX1.SetDataBinding(cities.Tables[0], "");
gridEX1.RetrieveStructure();

 

I was binding to the Janus GridEx Control, which is why you see gridEX1 above. You could easily replace those 2 lines with

 

dataGridView1.DataSource = cities.Tables[0].DefaultView;

 

Inserting a Row into Excel Using ADO.NET

Here I will add a 4th city, Tampa, to the list of cities in Florida. This inserts it right into the Excel Worksheet as you would expect.

 

string connectionString = @"Provider=Microsoft.Jet.
   OLEDB.4.0;Data Source=Book1.xls;Extended
   Properties=""Excel 8.0;HDR=YES;""";

DbProviderFactory factory =
   DbProviderFactories.GetFactory("System.Data.OleDb");

using (DbConnection connection = factory.CreateConnection())
{
    connection.ConnectionString = connectionString;

    using (DbCommand command = connection.CreateCommand())
    {
        command.CommandText = "INSERT INTO [Cities$]
         (ID, City, State) VALUES(4,\"Tampa\",\"Florida\")";

        connection.Open();

        command.ExecuteNonQuery();
    }
}

 

Updating Excel Using ADO.NET

Let’s modify the name of the first city from Bradenton to Venice in the Excel Spreadsheet using ADO.NET:

 

string connectionString = @"Provider=Microsoft.Jet.
   OLEDB.4.0;Data Source=Book1.xls;Extended
   Properties=""Excel 8.0;HDR=YES;""";

DbProviderFactory factory =
   DbProviderFactories.GetFactory("System.Data.OleDb");

using (DbConnection connection = factory.CreateConnection())
{
    connection.ConnectionString = connectionString;

    using (DbCommand command = connection.CreateCommand())
    {
        command.CommandText = "Update [Cities$] Set City =
                                \"Venice\" WHERE ID = 1";

        connection.Open();

        command.ExecuteNonQuery();
    }
}

 

Conclusion

It is just too cool that we can use ADO.NET and the OleDb Managed Data Provider in the .NET Framework to insert, update, and delete information in an Excel Spreadsheet like it was a database.

Source: http://www.davidhayden.com/blog/dave/archive/2006/05/26/2973.aspx

From past few weeks whenever I tried to open any download code sample it gives me error

“cannot be opened because its project type (.csproj) is not supported by this version of the application.
To open it, please use a version that supports this type of project.”

I am using Visual Studio 2008 with SP1.

Finally today I got the solution and it works fine for me …. :) Might be it will be a bug for VS-2008 :(

Here is the solution for it.

Go to Start> All Programs > Visual Studio 2008 > Visual Studio Tools > Click Visual Studio 2008 Command Prompt. Type the below command and press enter.

devenv.exe /resetskippkgs

It opens Visual Studio 2008 IDE and finally everything was OK .

 

Multithreading is tough. This is what John Robbins says about it in his excellent book Debugging Microsoft .NET 2.0 Applications:

“Don’t do it… Make sure there’s no other way you can structure your program before you decide to incorporate multithreading into your application… you are easily adding a minimum of an extra month of development and testing to your schedule”. I agree with it completely. But there are times multithreading is unavoidable. Especially when more and more Services popping up in the wild…

From Asynchronous Pages in ASP.NET 2.0

Customer Case Study

I am working with the customer to improve their ASP.NET 2.0 application performance. The application issues multiple requests to the backend middleware that is exposed as a web service. The application cannot get a hold on the actual proxies rather it is provided with the components that wrap the web services proxies. The application needs to issue concurrent  requests. Serial request would result in serious latency which is unacceptable by end users.

Analysis

Since we cannot get hold on web services proxies we cannot utilize available asynchronous methods available with it: BeginMyMethod/EndMyMethod and MyMethodAsync/MyMethodCompleted. But we definitely can utilize another option available with ASP.NET 2.0 – registering asynchronous tasks using PageAsyncTask class.

The following information is based on the following materials:

PageAsyncTask Implementation Steps

This is the summary of the steps to implement and register PageAsyncTask:

  • Create a class that contains lengthy operation
  • Declare AsyncTaskDelegate
  • Add OnBegin, OnEnd, OnTimeout methods to the class
  • Mark the calling page as Async=”true”
  • Register the PageAsyncTasks in the ASPX page and execute it

You can grab the Visual Studio 2008 project with the implementation from my SkyDrive here:

Code optimization: Memory management in .NET, part 2

In the .NET world, memory management is automatic. The recollection of memory, which is not in use, executes as a background task and lets the developer focus more on the task at hand rather than the plumbing work. The first part in this series ongarbage collection dealt with how garbage collection in .NET works. In this article, I’ll take a look at the interfaces exposed to the developer to aid and control garbage collection.

The Dispose design pattern: IDisposable, Dispose, and Finalize
The Common Language Runtime (CLR) cannot clean up resources like database connections, window handles, and file handles. Therefore, it is necessary for the developer to provide mechanisms for cleaning up these unmanaged resources. The clean up for this can be implemented in the Finalize method. The Finalize method is implemented as a destructor in C# language. The calling of Finalize is still under the control of the garbage collector.

Usually, you would need a deterministic way to clean up these unmanaged resources like file handles. For example if you have opened a file for reading and you have finished loading the contents of the file into a buffer, you might want to explicitly close the file handle. For this explicit clean up, .NET provides the dispose design pattern.

Objects which need explicit clean up of unmanaged resources implement theIDisposable interface. The IDisposable interface consists of the Dispose method, which unlike the Finalize method is under the control of the developer.

Since a call to Dispose represents an explicit clean up, it would not be necessary for the Garbage Collector to collect these objects. Hence a Dispose method should contain a call to GC.SuppressFinalize() notifying the garbage collector that finalization is not needed on that object.

The recommended practice is to implement both Finalize as well as Dispose methods on an object which needs to clean up unmanaged resources. The Finalize method would serve as a backup mechanism in the event that the Dispose is never called. The garbage collector would perform the object finalization and prevent a permanent leak of the unmanaged resource.

Figure A
Dispose design pattern

The code snippet in Listing A demonstrates these concepts more clearly.

The Listing A class SampleClass uses a file handle which is an unmanaged resource. Hence, it becomes necessary for this object to implement IDisposable and also to provide a Finalize method.

The cleanup code, which is the clean up of the file handle, is part of the Disposemethod. The GC.SuppressFinalize() is also called once the unmanaged resource has been cleaned up.

The class also provides the destructor (Finalize method). This again contains the code for clean up of the unmanaged resource, which is the file handle.

Weak references
The .NET Framework provides another interesting feature which can be used in implementing various caches. This is the concept of weak reference implemented in .NET as the System.WeakReference class. A weak reference provides a mechanism for referencing an object with the advantage that the referenced object would be available for garbage collection. The ASP.NET cache uses weak references. If the memory usage becomes too high the cache is cleaned up.

Forcing garbage collection
The .NET Framework exposes the System.GC class to the developer to control some aspects of the garbage collector. Garbage collection can be forced by invoking theGC.Collect method. The general advice is not to invoke the garbage collector manually and leave the decision of garbage collection to be automatic. In certain situations, the developer can justify that forcing garbage collection can provide a performance boost. However, great care should be taken when using this method because whenever the garbage collector runs, it suspends all currently executing threads. The GC.Collectmethod should not be located in a place where it would be called frequently. Doing so would degrade the performance of the application.

Server build and workstation build in .NET
The .NET Framework consists of two builds of the same CLR, each tuned for a specific purpose. These are classified as the server runtime and the workstation runtime, and are implemented in the mscorsvr.dll and mscorwks.dll, respectively. The server build of the CLR is built to take advantage of multiprocessing so that garbage collection can be done in parallel. On a single processor machine only the workstation build gets loaded and it is not possible to load the server build.

Also, there is a further setting known as concurrent garbage collection andnonconcurrent garbage collection for the garbage collector. The nonconcurrent setting is used for server environments where the application does not need to be responsive. In a client environment where a user interface is present and the application needs to be responsive, the concurrent setting is used.

Figure B

Processor environments

Microsoft has created some default settings on the project templates available in Visual Studio .NET, and an ASP.NET application should be able to take advantage of multiprocessors and load up the server build of the CLR. However, since a Windows application is usually user-interface rich, it would load the workstation build of the CLR.

It is possible to override these settings and control which build of the CLR would get loaded on a multiprocessor machine by using the CorBindToRuntimeEx API.

Productivity
With the Dispose design pattern, used in conjunction with the two CLR builds, developers can clean up unmanaged resources. The .NET Framework provides the infrastructure for garbage collection, freeing the developer from the task of keeping track of memory clean up. The developer needs to keep track of only the unmanaged resources which he has used, thus making life easier for the developer and improving productivity.

The .NET Framework provides memory management techniques that differ from the way memory management worked in a COM-based world. The memory management in COM was through reference counting. .NET provides an automatic memory management technique that involves reference tracing. In this article, we’ll take a look at the garbage collection technique used by the Common Language Runtime (CLR).

Automatic memory management: How different is it?
In reference counting, the reference count is increased each time memory is allocated for an object. The count is decreased whenever an object goes out of scope. The memory is reclaimed when the reference count reaches zero. This reference counting is manually managed by the developer in a language such as C++. If the developer fails to decrease the reference count when an object is freed, a memory leak is created. Also, the developer might decrease the reference count when he or she is not supposed to, which leads to memory being reclaimed before the proper time.

In comparison, in the managed world of .NET, the memory is handled by CLR. The task of garbage collection runs in the background, and the developer doesn’t have to spend time checking for memory leaks.

The garbage collection algorithm
The garbage collector runs when the memory heap is full. It starts from the root objects that are identified by the JIT compiler and traverses the object chain, tracing the references and adding them to the graph. The application roots are usually global and static object pointers.

When there’s an attempt to add an object that is already present on the graph, the garbage collector stops. In this way, the garbage collector recursively traverses all objects that are linked from the application root objects. Once the traversal is complete, the graph contains all objects that are somehow reachable. Any object that isn’t part of this graph is not reachable and therefore considered garbage. Each object that can’t be reached is marked and then collected.

Figure A
Memory blocks

In Figure A, blocks 1, 3, and 5 are reachable from the application roots. Blocks 2 and 4 are not reachable and hence can be marked for collection. Once the collection is complete, the memory space is compacted. That is, all the objects are moved so that they occupy a contiguous block of memory.

However, there’s one caveat to automatic memory management. The garbage collection algorithm is complex and runs only periodically, which means the memory is not freed immediately after a variable goes out of scope. This type of memory management is referred to as nondeterministic finalization. Only when the memory usage reaches a threshold will the garbage collector be triggered and trace through the object references to reclaim the memory. The main drawback of this method is that it doesn’t give the programmer the precise control as to when the objects are destroyed.

Circular references
Circular reference is a problem that occurs when there are two objects that refer to each other. Let’s say you have Class A that refers to Class B. If Class B also refers to Class A, then we have a circular reference. This happens in many situations. A typical example for this is a parent-child relationship between objects, where the child interacts with the parent object and also holds a reference to the parent object. This could lead to objects that would not get cleaned up until the application was shut down. The .NET way of garbage collection solves the problem of circular reference because the garbage collector is able to clean up any object that is reachable from the root.

Generations
The garbage collector algorithm is highly optimized. As it forms the graph and traces the references, the garbage collector further divides the graph into subgraphs called generations. The CLR classifies the heap in three generations. The objects that are created newly are maintained in generation 0. When the references to these objects are held for a long time, they survive garbage collection. Such objects are then promoted to generation 1 and generation 2. This classification increases performance because the garbage collector can perform collections on a specific generation, as shown in Figure B.

Figure B

Generations

Usually, the short-lived objects that are frequently created and destroyed remain in generation 0. The garbage collector performs a collection on generation 0 only when generation 0 is full. This happens when a request is made for the creation of a new object and there’s insufficient memory to allocate for that object. If the memory reclaimed from generation 0 is sufficient to create the object, the garbage collector does not perform the collection on other generations.

Good coding practices
Knowing the intricacies of how the CLR manages garbage collection should aid developers in writing management code. Automatic garbage collection is designed to complement good coding practices, but not to replace it. In the next installment in this two-part series, we’ll look at the aspects of garbage collection that are under the developer’s control.

Powered by WordPress | Theme: by 85ideas. Editor by Khoanguyen