Archive for ◊ March, 2010 ◊

Author:
Thursday, March 25th, 2010

Performance is a very critical requirement to make a project successful which is often times not captured at all or to a details which is required. Defining a Performance Acceptability matrix, Physical environmental plan etc, should be given same importance as functional requirements. Anyways, Performance requirements itself is a topic for another blog.  Below are my finds / info I stumbled upon during my recent encounter with some performance related challenges.

Some of the tests were:

Using a DataReader vs. a DataSet

The DataReader was of course faster. It was faster by 16% in this particular case.

Using an ArrayList of Data Holders

People sometimes put the data from a reader into a data holder class (In our case, Business Entities). This approach was almost no different to the pure DataReader approach (as expected).

SQLDataReader vs. OleDBDataReader

Going with native drivers is always better. The SQLDataReader was 115% faster than going through OLE.

Using Inline SQL vs. Stored Procedures

There was next to no difference in performance of using the stored proc versus the inline SQL in this experiment. This is partly due to the fact that this is JUST a SELECT statement, and SQL Server can cache these statements. This doesn’t mean that you shouldn’t use stored procedures!

But it’s important to make sure to club multiple SQL statements wherever possible to make a single database call.

DataReader Column Reference: By Name, Ordinal, or GetString()

The choices:

  • dr["ProductName"]
  • dr[0]
  • dr.GetString(0)

The order of speed? dr[0] was the fastest, followed by dr["ProductName"], followed by dr.GetString(0) as it has to do the conversion.

Inline (DataReader) vs. Controls (DataGrid)

The inline script was 233% faster than a DataGrid component.

ViewState enabled, or disabled

DataGrid with ViewState disabled is 66% faster than DataGrid with ViewState enabled.

Caching comes into play: DataGrid with: no caching, data caching, output caching

With data caching you get a 637% faster operation. With output caching you get an infinite improvement ;)

Category: .Net  | Leave a Comment
Author:
Wednesday, March 24th, 2010

Before I discuss about ItemsControl in Silverlight, I want to mention what exactly I needed to implement that lead me to ItemsControl. 

I needed a flexible Custom Control (let’s call it MyItemsControl henceforth) which can display Repeated Items like a Silverlight Data Grid. But it has to be fully customizable in terms of the presentation of the Grid, the presentation of the Items etc.

Important thing which I have to mention is the Data Source. The Data source for this control is any Xml of the following structure. 

<Items>

    <Item>

        <Attribute1></Attribute1>

        <Attribute2></Attribute2>

        <Attribute3></Attribute3>

            .    .    .

          .    .    .

    </Item>

</Items> 

Note that the Xml source can have any Element Names.

 And the way MyItemsControl has to be used is Drop the Control in a Xaml and configures the Presentation of the Grid in the Xaml. Specify the Source Xml as one of the Attributes on the Control. 

So now let’s see how this can be built using ItemsControl in Silverlight.

Since I have mentioned that I want to specify the presentation of the Control as part of the Xaml inside MyItemsControl, I require my control class to have Children property. So MyItemsControl should inherit Grid class (or even Stack Panel & Canvas).

Note that this is one of the reason I didn’t not use UserControl because it does not inherit from Panel class. 

public class MyItemsControl : Grid, IDisposable {} 

Once I have the ability to define childeren in the control I now add the Silverlight ItemsControl to it. This control has the following skeleton.

 

 Basic MyCustomControl Xaml 

<my:MyItemsControl RecordCount=”5″ x:Name=”control_001″ BindingItemsControl=” XML_Template” XMLUrl=”http://XMLSource/datasource.xml”>

    <ItemsControl x:Name=”XML_Template”>

        <ItemsControl.Resources>

            <!–THE BELOW RESOURCE IS MANDATOR AAND IT IS REFERENCED BU EACH DATA ITEM.–>

            <my:XMLItemConverter x:Key=”conv” />

        </ItemsControl.Resources>

 

        <ItemsControl.Template>

            <!–THE CONTAINER FOR OVER ALL LAYOUT INCLUDING HEADER, IF ANY

                                THIS CAN BE ANY VALID XAML–>

            <ControlTemplate TargetType=”ItemsControl”>

<!–INSIDE THE CONTROL TEMPLATE THE ITEM PRESENTER REPRESENT THE ACTUAL DATA ITEM CONAINER–>

                <ItemsPresenter/>

            </ControlTemplate>

        </ItemsControl.Template>

        <ItemsControl.ItemsPanel>

            <ItemsPanelTemplate>

                <!–THIS SECTION DEFINES THE ARRANGEMENT OF ITEMS. SINCE

                ALWAYS ITEMS ARE ATACKE, IT WILL CONTAIN EITHER GRID OR STACK PANEL–>

            </ItemsPanelTemplate>

        </ItemsControl.ItemsPanel>

        <ItemsControl.ItemTemplate>

            <DataTemplate>

<!–THIS SECTION CONTAINS THE XAML FOR THE ITEM. IT CAN CONTAIN ANY INDEPENDENT VALID XAML–>

            </DataTemplate>

        </ItemsControl.ItemTemplate>

    </ItemsControl>

</my:XMLItemsControl> 

Let’s discuss a few points about the above Xaml. 

  1. The parent control is MyCustomControl which has an attribute RecordCount. This basically controls the no.s of Items that are to be shown at a time.
  2. XMLUrl is the Url of the Data source that the control will be bound to.
  3. BindingItemsControl specifies the control name of ItemsControl that my control has to bind Xml data to.
  4. The remaining sections of the ItemsControl are self explanatory.
  5. I will discuss about XMLItemConverter further below.

 

Controling the number of Items to Bind at a time.

The RecordCount attribute can be used as per the requirements. Let’s say you want to bind first 5 items to the ItemsControl and then after 20 sec you bind next 5 items and so on. For this you can have a storyboard or a timer to control the interval and then rebind next 5 items every time. You can pull all the items from XML source once for all during the load of the control and then use Linq to bind only 5 subsequent items every time. You might even trigger the Rebinding on occurrence of some user event like €œGet Next Items€.

 void MyItemsControl_Loaded(object sender, RoutedEventArgs e)

        {

            if (!string.IsNullOrEmpty(BindingItemsControl))

            {

   _bindingItemsControl = (ItemsControl)((FrameworkElement)this.Parent).FindName(BindingItemsControl); 

                if (_bindingItemsControl != null)

                {

                    xItemsCache = XMLItemsCache.GetXMLItems(XMLUrl); 

                    if (!xItemsCache.IsFetchComplete)

                    { xItemsCache.ItemsLoadComplete += new XMLItemsCache.DlgItemsLoadComplete(ShowItems);

                        xItemsCache.InitXMLItemsCache();

                    }

                    else                    {

                        ShowItems();

                    } 

                }

            }

        }

 void strBrdLoop_Completed(object sender, EventArgs e)

        {

            int temp = LoadItems();

            if (temp != -1)

                strBrdLoop.Begin();

            else            {

                strBrdLoop.Stop();

            }

        } 

        private int LoadItems()

        {            if (!string.IsNullOrEmpty(XMLUrl))

            {

                XMLItemsCache xItems = XMLItemsCache.GetXMLItems(XMLUrl); 

                int itemIndex = GetCurrentItemIndex(PageUrlKey);

List<Dictionary<string, string>> temp = xItemsCache.GetNextItems(RecordCount, ref itemIndex);

                _dictPageItemIndex[PageUrlKey] = itemIndex; 

                _bindingItemsControl.ItemsSource = temp; 

                return itemIndex;

            }            else

                return -1;        }

 

Binding of XML items to Item Template controls. 

Till now we know how to control the binding of Items to the control. Now we will see how actually the contents of Xml items get bound to each TextBLock or MediaElement or Image in the ItemsTemplate 

<ItemsControl x:Name=”MY_XML_Template”>

                <ItemsControl.Resources>

                    <my:XMLItemConverter x:Key=”conv” />

                </ItemsControl.Resources>

                <ItemsControl.Template>

                    <ControlTemplate TargetType=”ItemsControl”>

                        <StackPanel>

            <TextBlock Text=”{Binding ConverterParameter=Header, Converter={StaticResource conv}}” />

                            <ItemsPresenter />

                        </StackPanel>

                    </ControlTemplate>

                </ItemsControl.Template>

                <ItemsControl.ItemsPanel>

                    <ItemsPanelTemplate>

                        <StackPanel Orientation=”Vertical” />

                    </ItemsPanelTemplate>

                </ItemsControl.ItemsPanel>

                <ItemsControl.ItemTemplate>

                    <DataTemplate>

                        <Border Background=”Beige” BorderThickness=”4″ CornerRadius=”10″ ScrollViewer.VerticalScrollBarVisibility=”Visible”>

            <Grid VerticalAlignment=”Stretch” Margin=”4,4,4,4″ Background=”Red” Height=”150″>

                                <Grid.RowDefinitions>

                                    <RowDefinition Height=”2*” />

                                    <RowDefinition Height=”6*” />

                                    <RowDefinition Height=”2*” />

                                </Grid.RowDefinitions>

                                <Grid.ColumnDefinitions>

                                    <ColumnDefinition Width=”2.5*” />

                                    <ColumnDefinition Width=”2.5*” />

                                    <ColumnDefinition Width=”5*” />

                                </Grid.ColumnDefinitions>

                                <TextBlock Grid.Row=”1″ Grid.Column=”1″ Text=”Address :” HorizontalAlignment=”Right” />

                                <TextBlock Grid.Row=”2″ Grid.Column=”1″ Text=”DOB     :” HorizontalAlignment=”Right” />

                                <TextBlock Text=”{Binding ConverterParameter=Name, Converter={StaticResource conv}}” TextWrapping=”Wrap” x:Name=”mytext” Grid.ColumnSpan=”2″ Grid.Row=”0″ Grid.Column=”0″ HorizontalAlignment=”Left” />

                                <TextBlock Text=”{Binding ConverterParameter=DOB, Converter={StaticResource conv}}” Grid.Row=”2″ Grid.Column=”2″ HorizontalAlignment=”Left” />

                                <TextBlock Text=”{Binding ConverterParameter=Address, Converter={StaticResource conv}}” Grid.Row=”1″ Grid.Column=”2″ HorizontalAlignment=”Left” />

                                <Image Source=”{Binding ConverterParameter=Snap, Converter={StaticResource conv}}” Grid.Row=”1″ Grid.Column=”0″ Grid.RowSpan=”2″ VerticalAlignment=”Center” HorizontalAlignment=”Left” Height=”127″ Width=”127″ />

                            </Grid>

                        </Border>

                    </DataTemplate>

                </ItemsControl.ItemTemplate>

            </ItemsControl> 

First of all, if you look at line of code 

List<Dictionary<string, string>> temp = xItemsCache.GetNextItems(RecordCount, ref itemIndex);

 Each xml item are transformed into Dictionary<string, string>. So lets say our Xml is something like 

<Persons>

  <Person>

    <Name>Tom</Name>

    <DOB>15/02/1983</DOB>

    <Snap>http://img1.jurko.net/wall/paper/tom_cruise_2.jpg</Snap>

    </Person>

</Persons> 

Then one list Item will contain a dictioanry

<Name, Tom>

<DOB, 15/02/83>

<Snap, http://img1.jurko.net/wall/paper/tom_cruise_2.jpg>

 

For each Item, there will be such Dictionary built. Following is the code to build such a dictionary.

 void wc_OpenReadCompleted(object sender, OpenReadCompletedEventArgs e)

        {

            if (e.Error != null || e.Result == null)

            {

                IsFetchComplete = true;

                return;

            }

            using (Stream s = e.Result)

            {

                try

                {

                    XDocument xDoc = XDocument.Load(s);

                    string itemNodeName = xDoc.Root.Descendants().FirstOrDefault<XElement>().Name.LocalName;                   

                    List<XElement> lstElements = xDoc.Descendants(itemNodeName).ToList<XElement>();

                    foreach (XElement ele in lstElements)

                    {

                        Dictionary<string, string> d = new Dictionary<string, string>();

                        foreach (XElement itemEle in ele.Elements())

                        {

                            if (!d.ContainsKey(itemEle.Name.LocalName))

                                d.Add(itemEle.Name.LocalName, itemEle.Value); 

                        }

                        MYItems.Add(d);

                    }

                    IsFetchComplete = true;

                    this.ItemsLoadComplete();                    

                }

                catch (Exception ex)                {                    return;                }

            }

 

Custom Binding converter 

Now once you bind the List of such Dictionalries, rest is taken care by the Custom Binding Converter class that knows how to bind each control to items in Dictionary. Here is the class for Binding Converter. 

public class XMLItemConverter : IValueConverter

    {

public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)

        {            object result = string.Empty;

            Dictionary<string, string> columnData = (Dictionary<string, string>)value;

            if (columnData.ContainsKey(parameter.ToString()))

            {                result = columnData[parameter.ToString()];            } 

            return result.ToString();

        }

        public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)

        { throw new NotImplementedException(); }

    } 

I guess now we can make sense of the Xaml <my:XMLItemConverter x:Key=”conv” />.

Here we are specifying the converter that the ItemsControl should use while binding to the Controls. The converter knows how to bind the Dictionary items to the appropriate attribute of the control.

 E.g.

<TextBlock Text=”{Binding ConverterParameter=Header, Converter={StaticResource conv}}” /> 

<Image Source=”{Binding ConverterParameter=Snap, Converter={StaticResource conv}}” Grid.Row=”1″ Grid.Column=”0″ Grid.RowSpan=”2″ VerticalAlignment=”Center” HorizontalAlignment=”Left” Height=”127″ Width=”127″ /> 

In the above Xaml for Image, we specify Source Converter parameter as Snap and the converter class (in this case specified as a Resource above) as conv. 

 

Unlike DataGrid control this controls allows us to be extremely flexible while presenting the Data and also read the data from a very simple XML format.

Category: Silverlight  | 3 Comments
Author:
Wednesday, March 24th, 2010

Concept of Data Modeling

The goals of this article are to overview fundamental data modeling skills that all developers should have, skills that can be applied on both traditional projects that take a serial approach to agile projects that take an evolutionary approach. Every software or IT professional should have some conceptual idea about Data modeling. They don’t need to be experts at data modeling, but they should be prepared to be involved in the creation of such a model, be able to read an existing data model, understand when and when not to create a data model, and appreciate fundamental data design techniques. Through this article I am introducing these skills. The primary audience for this article is application developers who need to gain an understanding of some of the critical activities performed by an Agile DBA. This understanding should lead to an appreciation of what Agile DBAs do and why they do them and it should help to bridge the communication gap between these two roles.

What is Data Modeling?

Data modeling is the act of exploring data-oriented structures. Like other modeling artifacts data models can be used for a variety of purposes, from high-level conceptual models to physical data models. From the point of view of an object-oriented developer data modeling is conceptually similar to class modeling. With data modeling you identify entity types whereas with class modeling you identify classes. Data attributes are assigned to entity types just as you would assign attributes and operations to classes. There are associations between entities, similar to the associations between classes €€œ relationships, inheritance, composition, and aggregation are all applicable concepts in data modeling.
Traditional data modeling is different from class modeling because it focuses solely on data €€œ class models allow you to explore both the behavior and data aspects of your domain, with a data model you can only explore data issues. Because of this focus data modelers have a tendency to be much better at getting the data €œright€ than object modelers. However, some people will model database methods (stored procedures, stored functions, and triggers) when they are physical data modeling. It depends on the situation of course, but I personally think that this is a good idea and promote the concept in my UML data modeling profile.
Although the focus of this article is data modeling, there are often alternatives to data-oriented artifacts (never forget Agile Modeling’s Multiple Models principle). For example, when it comes to conceptual modeling ORM diagrams aren’t your only option €€œ In addition to LDMs it is quite common for people to create UML class diagrams and even Class Responsibility Collaborator (CRC) cards instead. In fact, my experience is that CRC cards are superior to ORM diagrams because it is very easy to get project stakeholders actively involved in the creation of the model. Instead of a traditional, analyst-led drawing session you can instead facilitate stakeholders through the creation of CRC cards.

Type of Data Models

There are three types of data models practiced in the industry:
€¢ Conceptual data models. These models, sometimes called domain models, are typically used to explore domain concepts with project stakeholders. On Agile teams high-level conceptual models are often created as part of your initial requirements envisioning efforts as they are used to explore the high-level static business structures and concepts. On traditional teams conceptual data models are often created as the precursor to LDMs or as alternatives to LDMs.
€¢ Logical data models (LDMs). LDMs are used to explore the domain concepts, and their relationships, of your problem domain. This could be done for the scope of a single project or for your entire enterprise. LDMs depict the logical entity types, typically referred to simply as entity types, the data attributes describing those entities, and the relationships between the entities. LDMs are rarely used on Agile projects although often are on traditional projects (where they rarely seem to add much value in practice).
€¢ Physical data models (PDMs). PDMs are used to design the internal schema of a database, depicting the data tables, the data columns of those tables, and the relationships between the tables. PDMs often prove to be useful on both Agile and traditional projects and as a result the focus of this article is on physical modeling.

How to Model Data

It is critical for an application developer to have a grasp of the fundamentals of data modeling so they can not only read data models but also work effectively with Agile DBAs who are responsible for the data-oriented aspects of your project. Your goal reading this section is not to learn how to become a data modeler, instead it is simply to gain an appreciation of what is involved.
The following tasks are performed in an iterative manner:
€¢ Identify entity types
€¢ Identify attributes
€¢ Apply naming conventions
€¢ Identify relationships
€¢ Apply data model patterns
€¢ Assign keys
€¢ Normalize to reduce data redundancy
€¢ Denormalize to improve performance

We will see description of each task and more about data modeling in next blog.

Category: Data Warehouse | Tags: ,  | Leave a Comment
Author:
Wednesday, March 24th, 2010
Parsing and executing the Javascript which is coming from ajax response

When we are using an ajax call for loading the content of a page the Javascript inside the ajax response will not be executed. In this case we can use the below javascript function for parsing and executing the javascript code.

You just need to call the below function with ajax response as paramaeter for executing your javascript inside ajax response.

Ex: parseScript(ajaxResponse);

<script>
function parseScript(_source) {
var source = _source;
var scripts = new Array();

// Strip out tags

while(source.indexOf(“<script”) > -1 || source.indexOf(“</script”) > -1) {

var s = source.indexOf(“<script”);
var s_e = source.indexOf(“>”, s);
var e = source.indexOf(“</script”, s);
var e_e = source.indexOf(“>”, e);

// Add to scripts array
scripts.push(source.substring(s_e+1, e));

// Strip from source
source = source.substring(0, s) + source.substring(e_e+1);

}

// Loop through every script collected and eval it
for(var i=0; i<scripts.length; i++) {
try {
eval(scripts[i]);
}
catch(ex) {
// do what you want here when a script fails
}
}

// Return the cleaned source
return source;
}
</script>

Category: PHP  | Leave a Comment
Author:
Tuesday, March 23rd, 2010

This document helps in resolving the CodeAnalysis Warning CA1002 which we usually get when we are trying to return a list from a query using Linq.

Consider the below mentioned query which results in CA1002 warning Do not expose generic lists when we run the code analysis.

public static List<GroupForDisplay> GetGroupsByContactId(int contactId)

        {

            using (Extranet ent = new Extranet()) {

                var groups = (from manager in ent.Manager

                              where manager.Contact.ContactId == contactId

                              orderby manager.Group.GroupId

                              select new GroupForDisplay

                              {

                                   GroupId = manager.Group.GroupId,

                                   GroupName = manager.Group.Name,

                                   LastLoggedInDate = manager.Group.LastLoggedInDate,

                                   ParentGroupId = manager.Group.ParentGroupId,

                                   ResponseShared = manager.Group.ResponseShared

                              }).ToList();

                return groups;

            }

        }

The warning message:

Warning 25 CA1002: Microsoft.Design : Change ‘List<GroupForDisplay>’ in ‘GroupDac.GetParentGroupsRecursively(GroupForDisplay, List<GroupForDisplay>, int)’ to use Collection<T>, ReadOnlyCollection<T> or KeyedCollection<K,V>  C:\Project\Action Planning Solution\Action.Planning.WebClient\Dal\GroupDac.cs        105     ActionPlanning.WebClient

CA1002 rule says that we should not expose a List<T> property because any one can Add, Remove or Insert without notifying the class which exposes the property.

And one other situation  is if we want to be notified when an item is added /Removed/Inserted in the list then we do not have any methods which would helps us in notifying this.

If we use the ReadOnlyCollection then it cannot be modified and also if we use collection then we can use easily notify when an item was Added/Removed.

To rectify the error when using LINQ we would first try to use IQualrable<T> or the IEnumarable<T> as shown below.

public static IQueryable<GroupForDisplay> GetGroupsByContactId(int contactId)

        {

            using (Extranet ent = new Extranet()) {

                var groups = (from manager in ent.Manager

                              where manager.Contact.ContactId == contactId

                              orderby manager.Group.GroupId

                              select new GroupForDisplay

                              {

                                  GroupId = manager.Group.GroupId,

                                  GroupName = manager.Group.Name,

                                  LastLoggedInDate = manager.Group.LastLoggedInDate,

                                  ParentGroupId = manager.Group.ParentGroupId,

                                  ResponseShared = manager.Group.ResponseShared

                              });

                return groups;

            }

        }

This would not show the warning message when we run the codeananlysis, however if we want to use the IQueryable<GroupForDisplay>/ IEnumerable<GroupForDisplay> that the above method is returning elsewhere in the application then we would get the objectdisposed exception as showbelow.

€œThe ObjectContext instance has been disposed and can no longer be used for operations that require a connection€.

In Linq we cannot iterate through query object oustside the scope of €˜Extranet ent’ context.We can iterate it ony within the context.

So to use retuned object we have to convert it to ToList () or ToArray () to actually create a List/Array of object that gets disconnected when the context is disposed, but they can be accessed without problem.

So to solve the CA1002 Warning we can use the array of GroupsForDisplay[] and return an array or we can also return  ICollection as shown below.

public static GroupForDisplay[] GetGroupsByContactId(int contactId)

        {

            using (Extranet ent = new Extranet()) {

                var groups = (from manager in ent.Manager

                              where manager.Contact.ContactId == contactId

                              orderby manager.Group.GroupId

                              select new GroupForDisplay

                              {

                                  GroupId = manager.Group.GroupId,

                                  GroupName = manager.Group.Name,

                                  LastLoggedInDate = manager.Group.LastLoggedInDate,

                                  ParentGroupId = manager.Group.ParentGroupId,

                                  ResponseShared = manager.Group.ResponseShared

                              }).ToArray();

                return groups;

            }

        }

 

Or

public static ICollection<GroupForDisplay> GetGroupsByContactId(int contactId)

        {

            using (Extranet ent = new Extranet()) {

                var groups = (from manager in ent.Manager

                              where manager.Contact.ContactId == contactId

                              orderby manager.Group.GroupId

                              select new GroupForDisplay

                              {

                                  GroupId = manager.Group.GroupId,

                                  GroupName = manager.Group.Name,

                                  LastLoggedInDate = manager.Group.LastLoggedInDate,

                                  ParentGroupId = manager.Group.ParentGroupId,

                                  ResponseShared = manager.Group.ResponseShared

                              }).ToList();

                return groups;

            }

        }

Category: .Net  | One Comment
Author:
Tuesday, March 23rd, 2010

When we do programming in Delphi we don’t need to dynamically create a component. If we drop a component on a form, Delphi handles the component creation automatically when the form is created. But we can also create components at run-time. Here I would like to explain how we can programmatically create components at run-time.

Dynamic Component Creation

There are two ways to dynamically create components. One way is to make a form (or some other TComponent) the owner of the new component. This is a common practice when building composite components where a visual container creates and owns the subcomponents. Doing so will ensure that the newly-created component is destroyed when the owning component is destroyed.

To create an instance (object) of a class, you call its “Create” method. The Create constructor is a class method, as opposed to virtually all other methods you’ll encounter in Delphi programming, which are object methods.

For example, the TComponent declares the Create constructor as follows:

constructor Create(AOwner: TComponent) ; virtual;

Dynamic Creation with Owners
Here’s an example of dynamic creation, where Self is a TComponent or TComponent descendant (e.g., an instance of a TForm):

with TTimer.Create(Self) do
begin
   Interval := 1000;
   Enabled := False;
   OnTimer := MyTimerEventHandler;
end;

Dynamic Creation with an Explicit Call to Free
The second way to create a component is to use nil as the owner. Note that if you do this, you must also explicitly free the object you create as soon as you no longer need it (or you’ll produce a memory leak). Here’s an example of using nil as the owner:

with TTable.Create(nil) do
try
   DataBaseName := ‘MyAlias’;
   TableName := ‘MyTable’;
   Open;
   Edit;
   FieldByName(‘Busy’).AsBoolean := True;
   Post;
finally
   Free;
end;

Dynamic Creation and Object References
It is possible to enhance the two previous examples by assigning the result of the Create call to a variable local to the method or belonging to the class. This is often desirable when references to the component need to be used later, or when scoping problems potentially caused by “With” blocks need to be avoided. Here’s the TTimer creation code from above, using a field variable as a reference to the instantiated TTimer object:

FTimer := TTimer.Create(Self) ;
with FTimer do
begin
   Interval := 1000;
   Enabled := False;
   OnTimer := MyInternalTimerEventHandler;
end;

In this example “FTimer” is a private field variable of the form or visual container (or whatever “Self” is). When accessing the FTimer variable from methods in this class, it is a very good idea to check to see if the reference is valid before using it. This is done using Delphi’s Assigned function:

if Assigned(FTimer) then FTimer.Enabled := True;

Dynamic Creation and Object References without Owners
A variation on this is to create the component with no owner, but maintain the reference for later destruction. The construction code for the TTimer would look like this:

FTimer := TTimer.Create(nil) ;
with FTimer do
begin
   …
end;

And the destruction code (presumably in the form’s destructor) would look something like this:

FTimer.Free;
FTimer := nil;
(*
Or use FreeAndNil (FTimer) procedure, which frees an object reference and replaces the reference with nil.
*)

Setting the object reference to nil is critical when freeing objects. The call to Free first checks to see if the object reference is nil or not, and if it isn’t, it calls the object’s destructor Destroy.

Dynamic Creation and Local Object References without Owners
Here’s the TTable creation code from above, using a local variable as a reference to the instantiated TTable object:

localTable := TTable.Create(nil) ;
try
   with localTable do
     begin
       DataBaseName := ‘MyAlias’;
       TableName := ‘MyTable’;
     end;
   …
   // Later, if we want to explicitly specify scope:
   localTable.Open;
   localTable.Edit;
   localTable.FieldByName(‘Busy’).AsBoolean := True;
   localTable.Post;
finally
   localTable.Free;
   localTable := nil;
end;

In the example above, “localTable” is a local variable declared in the same method containing this code. Note that after freeing any object, in general it is a very good idea to set the reference to nil.

 Do not mix a call to Free with passing a valid owner to the constructor. All of the previous techniques will work and are valid, but the following should never occur in your code:

with TTable.Create(self) do
try

finally
  Free;
end;

The code example above introduces unnecessary performance hits, impacts memory slightly, and has the potential to introduce hard to find bugs.

Note: If a dynamically created component has an owner (specified by the AOwner parameter of the Create constructor), then that owner is responsible for destroying the component. Otherwise, you must explicitly call Free when you no longer need the component.

A test program was created in Delphi to time the dynamic creation of 1000 components with varying initial component counts. The test program appears at the bottom of this page. The chart shows a set of results from the test program, comparing the time it takes to create components both with owners and without. Note that this is only a portion of the hit. A similar performance delay can be expected when destroying components. The time to dynamically create components with owners is 1200% to 107960% slower than that to create components without owners, depending on the number of components on the form and the component being created.

Analyzing the Results

Creating 1000 owned components requires less than a second if the form initially owns no components. However, the same operation takes roughly 10 seconds if the form initially owns 9000 components. In other words, creation time is dependant on the number of components on the form. It is equally interesting to note that creating 1000 components that are not owned takes only a few milliseconds, regardless of the number of components owned by the form. The chart serves to illustrate the impact of the iterative Notification method as the number of owned components increase. The absolute time required to create an instance of a single component whether owned or not, is negligible. Further analysis of the results is left to the reader.

The Test Program

You can perform the test on one of four components: TButton, TLabel, TSession, or TStringGrid (you can of course modify the source to test with other components). Times should vary for each. The chart above was from the TSession component, which showed the widest variance between creation times with owners and without.

Category: Delphi  | 5 Comments