Friday, May 30, 2008

Tools and Utilities

Tools and utility programs are essential helpers for programming. I learned a lots of tools from web, blogs and other people. I remembered that when I was working at one SCADA company about 7 years ago. One developer showed me Total Commander tool with his passion. He told me it is much better than Windows File Explorer and he cannot work without it.

Since then, I tried this tool and I fall in love with it. It helps a lot for file exploring, management, and software development. When I work any where, I always bring it with me.

Many other tools are also very good. Here is a list of tools Jean-Paul and Scott Handselman recommend:



I like to read JP's blog. Some of his blogs recommended some really good tools.

Read More...

Thursday, May 29, 2008

Find a Control in ASP.Net Page

One ASP.NET page is composed of one aspx or xml file for front-end UI design and a class either in C# or VB as server side codes related to the page and control events.

Unlike window form application, the code-behind class does not know controls on the page directly. You cannot directly access control instances. For example, a label or text box control within a GridView control's template.

Here is one function I use to get a control by id:

using System.Web.UI;
...
public class WebPageUtil
{
...
public static T FindControlRecursive<T>(Control root, string id) where T: Control
{
T found = null;
if (root != null)
{
found = root.FindControl(id) as T;
if (found == null)
{
if (root.ID == id)
{
found = root as T;
}
else if (root.Controls != null)
{
foreach (Control ctr in root.Controls)
{

found = FindControlRecursive(ctr, id);
if (found != null)
{
break;
}
}
}
}
}

return found;
}
...
}


Where Control is a System.Web.UI.Control. It has FindControl() method. It can only find control within a container control, or root in this case. For example, in a GridView control named as GridView1, a TableCell control in a selected row (GridView1.Rows[0]) may contain some Label or TextBox controls, which are defined within aspx page GridView1 control's template.

However, this call only search for controls directly placed within the current control. If the control is within the next or even deep level, you have to loop its children Controls to call recursively.

I use generic type method call to make the method very simple to use. Here are some examples:

GridViewRow row = GridView1.Rows[e.RowIndex] // e is GridViewUpdateEventArgs object
LinkButton btnSave = WebPageUtil.FindControlRecursive<LinkButton>(row, "btnSave");
if (btnSave != null)
btnSave.Visible = false;

Read More...

Thursday, May 08, 2008

SQL Server Project (3)

In a SQL Server Project, all the SQL Server Objects (SSO), such as stored procedures (SP), must be defined as public static methods. All these methods are marked with Microsoft.SqlServer.Server Attributes, so that they can be deployed as SQL Server Objects.

Let's see how a SSO is called in SQL Sever. For example, when a SP is called first time, the SQL server will load the assembly library from the database, as I mentioned that all the assemblies have to be registered in a DB, into memory. Then the specified static method is called. After the SP finishes its job, however, the assembly stays in the memory forever. I tested this feature with a simple SP and a private static integer counter in its class. The counter increases by 1 for each call. The counter stays in the memory with its last call increment for several days.

This is a quite interesting feature of the deployed SSOs. Actually, if you think it in the context of SQL service process, it is not hard to understand it. The SQL service process loads the assembly into memory. Since static methods are global available, they will stays as long as the SQL service process stays.

However, this posts a problem most developers do not realize. They assume that when a call is finished, all the related resources should be released. If the assembly is not well designed, it may cause memory leaks in a SQL server. For example, if some resources are not cleaned, these resources are left in the memory for each call. You can imagine that if the SSOs were called constantly, it would cause memory leak. Another issue is that if some resources are static and not cleaned, these resources are occupied in memory. As a result, the first call is fine, but the next call may get exception since they cannot access these resources.

Therefore, you have to pay attention to all the cleaning jobs. Make sure that all the resources are freed after the execution, including the case of the execution being interrupted by clients. For example, you have to handle ThreadAbortException exception.

Talking about exception handling, it is not recommended to handle or hide all the exceptions. For example, if you design a Trigger, you may want some exceptions thrown to SQL server so that any related failure would cause the SQL server to roll back transactions. Therefore, if you know how to handle some exceptions, you can handle them, otherwise, leave them alone.

There is a way to clean assembly from memory in SQL server. Run the following command to clean all the unused cache and free up memory:

DBCC FREESYSTEMCACHE ('ALL')

I run this command in a daily job for cleaning memory used during a day.

Read More...