Thursday, December 11, 2008

Shoestring toolkit for startup projects


Integrated Development Environments

Database Environment

  • SQL Server Express 2008 (available in the above download page)

Web Framework

More Frameworks might be added based on requirements.

ORM

Testing

No code would be accepted without proper tests and high code-coverage. More on it during our discussions.

Source Control

Register with xp-dev.com and give me your username. I would later post the details on how to checkout the source code. I would also show you on how to work with the source control using TortiseSVN tools. All our source code checks into the xp-dev project repository. More details later. For now, download the SVN tools from here.

Additional tools

  • Code Analysis – FxCop
  • Text Editor – InType
  • Command Line - PowerShell (Pick your version - x86 or x64 based on your CPU)
  • XAML Editor - KaXAML (for some XAML/WPF/Silverlight learning)
  • Paint.NET – Graphics
  • .NET Reflector - I will give you later, when required.

Feel free to comment on what you think or if you have good general tools in mind, advice me.

Monday, November 24, 2008

Debugging - Using the Java Debugger (jdb)

 

Goals
  1. Getting started with Java Debugger using command line tool JDB
  2. Doing simple debug operations using JDB
Let us get started
  • Write a simple java program and save it as Sample.java.
import java.lang.*;

public class
Sample
{
public static void main(String[] args)
{
System.out.println("Brought to you by "+getName(10));

}

public static String getName(int i)
{
int j = 20;
while(i>0)
i--;
System.out.println("Value of J is : "+j);
return http://krishnabhargav.blogspot.com;
}
}




  • Compile the java program such that the symbols are also generated, which is useful for debugging purposes. This is done as shown



javac -g Sample.java



  • Load the debugger with the Sample class. You do that with the command shown below



jdb Sample



  • Before we start any further, let us look at the list of commands that are useful for us. To get a help, type "help" in the jdb console menu.

    • list - display ten lines of source code, around the line at which the execution stopped


    • stop in <class>.<methodName> - breakpoint at the specified methodName in the Class <class>


    • stop at <class>:<lineNumber> - breakpoint at the specified line number in the class


    • locals - list the local variables in the current scope


    • dump <obj reference> - dumps the object whose reference is specified


    • print <obj reference> - prints the object whose reference is specified


    • set x = 10 - set's the value of the variable x to 10


    • eval 100+500 - evaluates the expression passed and displays the result.






  • Now let us start, first we need to set a breakpoint at main() method. We do that using "stop at" command.



stop at Sample.main



  • Now start running the program, use the "run" command.



run



  • You would notice the program to stop when it hits the breakpoint



Breakpoint hit: "thread=main", Sample.main(), line=7 bci=0
7 System.out.println("Brought to you by "+getName(10));



  • Now type the list command, and you get to see the code listing as shown



3    public class Sample
4 {
5 public static void main(String[] args)
6 {
7 => System.out.println("Brought to you by "+getName(10));
8
9 }
10
11 public static String getName(int i)
12 {



  • The => shows where the break point has been hit. Now we have option to step into the getName() method. For that type



step



  • Now type "list" again. The code listing would be shown



9            }
10
11 public static String getName(int i)
12 {
13 => int j = 20;
14 while(i>0)
15 i--;
16 System.out.println("Value of J is : "+j);
17 return http://krishnabhargav.blogspot.com;
18 }



  • Now let us skip the loop execution. For that let us first put a breakpoint at line number 16



stop at Sample:16



  • Now to resume execution, type "cont" command. It would execute till it hits the next breakpoint



cont



  • Now let us look at the local variables in the current context. For that type "locals" in the console as shown



main[1] locals
Method arguments:
i = 0
Local variables:
j = 20



  • Now let us try to modify the value of j on the fly, instead of 20, let us put the value as 100. For that



set j = 100



  • Now let us go back to the calling method. For that, type "step up"



step up


main[1] step up
> Value of J is : 100

Step completed: "thread=main", Sample.main(), line=7 bci=20
7 System.out.println("Brought to you by "+getName(10));



  • Now let us finish the execution till the end. For that just type "cont" again. You see the listing as shown.



main[1] cont
> Brought to you by http://krishnabhargav.blogspot.com


What next?


We have seen how to look at the local variables. We also have seen how to change the value of a variable in scope. But we have not seen how to work with dump <ref>, print <ref> and the other useful "eval" command. You could figure out doing this. But for now, try to repeat the debugging process again. Then set up a breakpoint at main() method and when it breaks, just type in "dump this". See what you get? You get an exception saying that you are currently either in a static method or native method, so to test the dump functionality, you would have to have a object in your scope. And then you can dump that. Suppose you have an instance of Point in your context. Then you can set pt.x using "set pt.x = 100", by this I mean to show that you can use set to manipulate all variables, even those that belong to an object.



Remote Debugging with JDB


Other important thing that we are missing in this tutorial is remote debugging using JDB. I would not present a step by step way to do that but for remote debugging a program, you need to

1. Start the program using Java command, as shown



java -Djava.compiler=NONE -Xnoagent -Xdebug
-Xrunjdwp:transport=dt_socket,address=2502,server=y,suspend=y
Sample


2. Attach jdb from the command line to the server. assuming it is running on localhost, it is done as shown.



jdb -attach localhost:2502


References


JDB Documentation

Using ANT for Java Development Builds

Objectives
  • Getting familiar with installation of ANT and setting classpath to be able to run ANT tasks
  • Get a top level view of using ANT to compile and run Java applications
  • Writing a simple ant build script
Software requirements
  • Apache ANT 1.7.0 - http://apache.ant.org
  • Java SDK 1.6 ( Java 1.5 would still work, but I prefer to run the latest stable release )
  • Simple XML editor [optional]. You can possibly use Notepad2 if you are running windows or use Vim if running Linux.

Before we actually dive into the installation and running ANT, let us understand what ant is and then we might have a strong reason on why one should use ANT scripts in their projects.

What is ANT? Why use it?

Apache ANT is one of the most widely used build tool. I am pretty sure most of you have worked with Make files and if Make is the ultimate build tool for any applications on Linux, Ant is the equivalent edition used mostly for Java applications ( and could be used for .NET applications too, but not many really care ). While Makefiles use plain text instructions, Ant uses XML based instructions. These xml files are usually called Ant Scripts, even though they do not have any script as such. It is just a set of tasks that we define, that we ask the ant tool to execute for us, thereby automating almost any process in a software development lifecycle. Ant pre-defines a set of tasks for compiling packages, running Java programs, creating JAR or WAR files, running Unit tests and a lot more. Ant is used across the industry, for its simplicity, portability and especially the power it brings to automation. You can integrate Ant with most of the popular IDE like Eclipse and Netbeans. Infact Netbeans generates an Ant script and it is executed whenever you build or run a file or a project. In the second tutorial, we look at how to integrate Ant with Eclipse and Netbeans.

Apart from the sheer simplicity that it brings into development process, to be practical, it adds value to your resume. As already mentioned, Ant is used scross the industry and as a prospective developer, you are required to be able to write Ant scripts. Coming back to the non-practical view, Ant scripts is the best way you can automate your process. Consider a simple Client-Server Program where you are required to first compile the programs, start the server, then start the client and each time you do that, even if you use IDE, you are supposed to do some amount of work. But with ant, you can automate the entire process. After the tutorial 2, you would still use IDE but would use Ant scripts to build and run your code. You would use IDE for debugging purposes, unless someone comes up with a tutorial on how to use Command line debugger that ships with JDK. Ok, enough of the theory, lets get started with some practical stuff!

Installing ANT
  1. Download Ant toolkit from http://mirrors.kahuki.com/apache/ant/binaries/apache-ant-1.7.0-bin.zip
  2. Extract the archive on to your local file system. Usually I place all my development tools in a special folder in D: drive called "development". This helps me quickly find any development tool, whenever needed.
  3. Now you need to add Ant to your command prompt path. I assume you are using Windows (for setting classpath on Linux, please visit my blog entry *here).
  4. If you path is set, then you can just type the command "ant" in any command prompt window and the command prompt would be able to locate your ant executable. To set the classpath on Windows,
    1. Right click on My Computer. Go to Properties and select the Advanced tab page. (In Vista, you right click on Computer, Go to Properties and then go to Advanced tab)
    2. Click on Environment variables. You get a new dialog window (image shown below). There are two types of variables, User and System Variables. We would now add a System Variable. To do that, first click New … button and create a new variable called "ANT_HOME". In the variable value, you give the path to the directory of Ant. In my case, it is "D:\Development\Apache-Ant-1.7.0". Click ok and now you see a new ANT_HOME variable set.
    3. Scroll down the list to locate "Path" variable. Select the variable and then click on Edit.. button. Now in the variable value textbox, append the statement "%ANT_HOME%\bin". A variable can have multiple values in which case, we seperate them using ";". The new value should look something like "previous values;%ANT_HOME%\bin". Take a look at the image shown below.

image

  1. Now test to see if you have correctly set your path. To do this, go to command prompt and type "ant". If everything works fine, you should see a message which says "build.xml does not exist!". This also should tell you that, default script file that ant looks for is a build.xml (in case of make it is Makefile)

Assuming, Ant is setup and ready to use, we would now write a simple "Hello" program in Java. The program takes in a command line argument and prints a message along with the argument passed.

Sample Java Program
package truebuddi.learning.ant;

import java.lang.*;

public class
HelloAntWorld
{
public static void main(String[] args)
{
if(args.length<1)
{
System.out.println("Invalid number of arguments. Program terminating ... ");
return;
//or System.exit(-1);
}

//if the execution reaches here, argument have been passed accurately.
System.out.println("Welcome to Ant world! I hope you executed the program via Ant");
String message = String.format("Arguments you passed : %s",args[0]);
//Looks like C format specifiers ! Yes it is!
System.out.println(message);
// print the message.
}
}



Save the file at a location like "D:\projectFolder\src\truebuddi\learning\ant\HelloAntWorld.java" (The section in bold should match with your package statement. I would then place my ant build file at "D:\projectFolder\build.xml". My directory structure looks like shown below.



image



Writing your first ant script


Now let us write a simple ant script that has two tasks - first to compile the program and the second to run the program. The complete Ant script looks something like shown below. Reference: http://ant.apache.org/manual/index.html



<!-- default=compile implies, the default task that is run when ant executes this script is the compile task -->
<
project name="LearningAnt" default="compile" basedir="."
>
<
description
>
First Ant build script to compile and run truebuddi.learning.ant.HelloWorld program
</description
>
<!--
set global properties for this build
-->
<
property name="src" location="src"
/>
<
property name="build" location="build"
/>

<
target name="init"
>
<!--
Create the build directory structure used by compile
-->
<
mkdir dir="${build}"
/>
</
target
>

<!--
depends="init" implies that before compile is actually run, init is executed
-->
<
target name="compile" depends="init" description="compile the source "
>
<!--
Compile the java code from ${src} into ${build}
-->
<
javac srcdir="${src}" destdir="${build}"
/>
</
target
>

<
target name="execute" depends="compile" description="Run the program"
>
<
java classname="truebuddi.learning.ant.HelloAntWorld"
>
<
arg value="I am running this from Ant!"
/>
<
classpath
>
<
pathelement location="build"
/>
</
classpath
>
</
java
>
</
target
>

<
target name="clean" description="clean up"
>
<!--
Delete the ${build} and ${dist} directory trees
-->
<
delete dir="${build}"
/>
<
delete dir="${dist}"
/>
</
target
>

</
project
>




  • Important points

    • Please take a look at default="compile" and depends="xxxx" attributes in the script. Read the comments.


    • javac is used as a tag which is a pre-defined ant task. It executes the java compiler on the code in the "src" folder and copies the output to build folder. Right now in this example, we do not use external libraries and if used we would have had them within classpath tags in the ant file. It would be evident in the future tutorials. For now, we just let the ant know that our classpath would have 'build' directory.


    • There are four target operations that ant can execute - init, compile, execute and clean.





Running the ant script


Having saved the above xml as "build.xml" in the project root folder, go to command prompt and navigate to the root. Run the following commands

1. To compile the program, run "ant". Since the default target is compile, the program would compile and you get output something like shown below.



image



2. To run the program, run the command "ant execute".



image



[Optional] The program could be executed as "java -classpath buddi truebuddi.learning.ant.HelloAntWorld message"



I hope this tutorial would get you started with using Ant to compile and run Java Programs. I have even shown you on how to set classpath in ant scripts, how to pass arguments to Java programs, shown you the ant tasks like java, javac, mkdir ,etc.

Updated MoneyManager Library : Better Money

Like I mentioned in my previous post, the MoneyManager library is coming off well. My super cool colleague has helped me identify some design flaws (actually I knew the design isn't right and he helped me fix some flaws with some nice ideas). End result? Look at the class diagram below. Now if you need to add a different source for the data, you create a class that derives from IFactory and if you wish to use Multithreaded functionality, then derive from MultiThreadFactory too. Simple enough, eh!
ClassDiagram1

Next I should work on the super cool WPF UI which has charts, analysis helpers and much more.

Friday, November 21, 2008

Better Money : Phase 1

I made pretty decent progress on the Better Money project that I started yesterday. Shown below is the class diagram for the MoneyManager library.

ClassDiagram1

I tried to make the MoneyManager library as generic as possible so that accounts can be pulled from any source, not just Wesabe. For the Wesabe, I wrote the implementation and is currently having only the root methods - just enough to get started.

The GUI would interface with the library through the MoneySource class, which is incomplete as of now. It has a Manager property which holds instance of the current MoneySourceManager. One such MoneySourceManager is the WesabeMoneySourceManager. MoneySourceManager is the interface IMoneySourceManager. The way MoneySourceManager fetches the Models is upto the implementation class. The WesabeMoneySourceManager makes use of WesabeClient, the REST API client to the Wesabe API as well as WesabeFactory which derives from MoneySourceFactoryBase. My idea is that any MoneySourceFactory that contains methods to build the models should inherit from MoneySourceFactoryBase. Right now, it is rather strange kind of inheritance but I plan to improve it with time. (WesabeFactory inherits from MoneySourceFactoryBase<XDocument,XElement> and GetTags() uses XElement while GetAccounts() uses XDocument. I know it is not great, but I promise to improve it.)

The maintainability code metric for the whole library is around 88, which I think is not great. I need to refactor the code to improve this.

The MoneySource class right now has only one manager, but more Managers could be added to the class. A MoneySourceManager has to derive from IMoneySourceManager. For example,

   1: public class ExcelMoneySourceManager : IMoneySourceManager


   2: {


   3:    private MoneySourceFactoryBase<object,object> Factory;


   4:    private InterfaceClient client; 


   5:    //Assumption: InterfaceClient would provide interface methods with the Excel sheet.


   6:  


   7:    //Methods to be implemented....


   8: }




I should improvise the structure and the design of the library. The next step would be to get hold of a good design patterns book and identify cases for improvements. Now that I know how the current design is, I would be able to identify the applicable patterns easily. This helps me grow as an architect.



By the way, I have not implemented the WesabeFactory to use XmlSerialization. Instead I used XLinq to identify the elements for reasons - did not want to spend time on matching the serialization attributes to the Wesabe XML returned and XmlSerialization is slow. The WesabeFactory speeds up quiet a few things by using Threadpool wherever applicable. More on the api later..

Thursday, November 20, 2008

Project : Better Money

Everyone says the economy is bad and we will all be in a crisis. And those who know me well can definitely say that my finance management skills are very bad. Now I wanted to utilize my programming skills to develop a personal finance analysis tool. The idea is to use the Wesabe API to get all my finance data and give it to a nice little WPF-based visualization tool - Better Money.

Wesabe, for those who do not know about this is a online money management tool. It is a great tool where you can add bank accounts and watch your income and expenditure. It is a great tool and the best part of it is that its just a startup!

I have gathered enough information and I know exactly on how to proceed with the development. I have not yet decided on the features that the tool shall have, but my initial plan is to develop a C# library to the Wesabe REST API. The documentation provided by Wesabi is excellent and tells you nothing more than what you really need. The C# library is intended to stand-alone so that anyone with much better GUI skills than me can utilize it instead of dealing with the REST calls. I would keep posting on the project progress every now and then. The intended release date for the C# library is 24th November 2008. As of the Better Money suite, I intend to release it before Christmas. Both the library and the suite would be free - do what ever you want as long as I do not get penalized.

If someone from Wesabe finds this post offensive and do not want me to release either the  code or the tool, then please send me an email at krishnabhargav@yahoo.com. The idea is not to make money but help others and in the process I do not want to be slammed with a lawsuit.

Technorati Tags:

MSDN WPF Forums : Hit a 100!

On September 24th 2008, I decided that I would like to improve my WPF skills. By that time, I already had decent understanding of some important concepts in WPF (minus Hit-Testing, Commands). And I always believed that contributing to forums helps others and at the same time it gives you great knowledge - you try things for others and in the process you learn something new with every post you make.

Finally, I reached 100+ answers which means that 103 of my posts were answers to the questions. It is a nice feeling to help people with 100 issues - big or small, it does not matter.

image

So, I gave 103 answers in less than 2 months, which I think is pretty decent given that I am working full-time and also a graduate student at UGA.

My profile

http://social.msdn.microsoft.com/Forums/en-US/users/#page:1;searchexpression:krishnabhargava

Wednesday, November 19, 2008

MSDN Question on WPF: MDI like WPF Window

Well, MDI are not supported in WPF and this is not a hack to create MDI applications in WPF. What we will be doing is to simulate MDI like behavior. The main window has two buttons one for Screen1 and another for Screen2. The XAML is shown below.

   1: <Grid>  


   2:         <Grid.RowDefinitions>  


   3:             <RowDefinition Height="40*" />  


   4:             <RowDefinition Height="222*" />  


   5:         </Grid.RowDefinitions>  


   6:         <StackPanel Grid.Row="0" Orientation="Horizontal">  


   7:             <Button Width="Auto" Click="Screen1_Click">Screen 1</Button>  


   8:             <Button Width="Auto" Click="Screen2_Click">Screen 2</Button>  


   9:         </StackPanel>  


  10:         <ContentPresenter Grid.Row="1" Name="ScreenHolder"></ContentPresenter>  


  11: </Grid>  



The Code Behind for the XAML is.



   1: Screen1 sc1 = new Screen1();  


   2: Screen2 sc2 = new Screen2();  


   3: private void Screen1_Click(object sender, RoutedEventArgs e)  


   4: {  


   5:     ScreenHolder.Content = sc1;  


   6: }  


   7:   


   8: private void Screen2_Click(object sender, RoutedEventArgs e)  


   9: {  


  10:     ScreenHolder.Content = sc2;  


  11: }  



Screen1 and Screen2 are User Controls whose XAML is shown below.



   1: <UserControl x:Class="MSDNSocial.Screen1"  


   2:     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"  


   3:     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">  


   4:     <Grid>  


   5:         <Label VerticalAlignment="Center" FontSize="20" HorizontalAlignment="Center">  


   6:             This is Screen 1  


   7:         </Label>  


   8:     </Grid>  


   9: </UserControl>  


  10: <!-- User control 2 -->


  11: <UserControl x:Class="MSDNSocial.Screen2"  


  12:     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"  


  13:     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">  


  14:     <Grid>  


  15:         <Label VerticalAlignment="Center" FontSize="20" HorizontalAlignment="Center">  


  16:             This is Screen 2  


  17:         </Label>  


  18:     </Grid>  


  19: </UserControl>  



When you click Screen1 button, screen1 appears and clicking screen2 shows screen2. Note that it is the same User Control that will be showed again and again. So the state should be essentially saved. Much like Page Navigation without crying out loud.

Tuesday, November 18, 2008

MSDN Question on WPF: KeyDown event and Space key

Most of us, at some point, faces this issue : KeyDown event handler does not detect Space key while PreviewKeyDown event handler does!

KeyDown event as one expects is raised when a key is "down". KeyDown event handler attached in XAML would miss some keys like "Space" and for a reason. The reason that I can think of is that Space bar invokes a command (like a toggle or mouse click if a button has focus). So when Space bar is pressed, it invokes the tunneling event "PreviewKeyDown" in which the event is marked as Handled. So, the KeyDown event handler is no longer invoked in this case. Note that KeyDown is an attached event (a XAML event mechanism which enables elements have events which they do not have in the first place).

As a workaround, you do not specify the event handler inside XAML and instead do it in Code-behind. If tx is a TextBox, then I set the KeyDown event handler as shown:

tx.AddHandler(TextBox.KeyDownEvent, new KeyEventHandler(TextBox_KeyDown),true);

The third argument is "handledEventsToo" which is false by default. Setting handledEventsTrue in the AddHandler method allows KeyDown event handler be invoked even for those keys which stops tunneling in the PreviewKeyDown event itself.


Even if there is a work around, it is recommended that you do not handled those events which are already handled - simply put, let the handledEventsTrue be always false. Setting it to true might result in unexpected behavior.

Monday, November 17, 2008

MSDN Question on WPF: Shrinking Focus Rectangle to Content

http://social.msdn.microsoft.com/Forums/en-US/wpf/thread/9c8b6e75-6970-4126-89ac-40dc6ca39b43

image

The requirement is that a Checkbox inside a grid, when gains focus should have its focus rectangle fit to the content, just in the WinForms example.

The XAML for the solution is shown below.
 

<Grid >
<
Grid.RowDefinitions>
<
RowDefinition Height="Auto" MinHeight="13" />
<
RowDefinition Height="Auto" MinHeight="13" />
</
Grid.RowDefinitions>
<
Grid.ColumnDefinitions>
<
ColumnDefinition />
</
Grid.ColumnDefinitions>
<
CheckBox HorizontalAlignment="Left" Grid.Row="0">Content will be put here</CheckBox>
<
CheckBox Grid.Row="1">Content would be put here again, another test checkbox</CheckBox>
</
Grid>


The idea is to set HorizontalAlignment of the focusable controls to Left which makes the Grid layout consume extra space only as needed instead of taking it on whole.  The screen shot of running application is shown below.



image


Hope this helps. By the way, the first screen shot has been pulled from the link I specified. If the author of the post happens to stumble upon this post and finds it offensive, I can remove the screen shot. I just did not want to spend time developing two prototypes showing just the issue when there was already a great screen shot available.

Friday, November 14, 2008

Performance of Collections in .NET

With some future prospects of writing a high scale LOB Silverlight application, I thought performance of the application would be crucial. I decided to look into writing optimized code and before that I decided to find out what is the performance impact of the collections that I use most commonly. To be specific, in this post, I only look at the performance of creating various collections of type int.

Large Collections

I wrote a simple performance test class which returns me collections of various types. Each method create a list of pretty large size.
public static int MAX = 19999999;
The results of the test program is shown below.

image

Name

Collection Type Explained

Ar Array (int[] array)
Ar_Enble array.AsEnumerable()
Ar_En_Cast IEnumerable<int> e = array;
List List<int>
IniList List<int> l = new List<int>(MAX);
ArList ArrayList
Range new List<int>(GetArray());
LL LinkedList<int>


From the results, it is obvious that an array is the fastest collection that you can use and on an average it is 28 times faster than ArrayList and 3 times faster than the List<T>.

Note that for this discussion, I only am using entries with green color. This is based on the assumption that GetArray() should be faster than first getting the array and then IEnumerable out of the array. Some of the key points I made out of this experiment:

  • The performance of an initialized list (IniList) is 1.3 slower than using plain array.
  • AsEnumerable() is slightly faster than the cast operation.
  • Do not use LinkedList, it is dead slow(50-70 times slower).
  • Do not use ArrayList, it is dead slow(28 times slower).
  • AddRange() or List created by passing an entire array is not faster than adding individual items to an capacity-set list, which is at least 4 times faster.
  • Use arrays when you can guess the size of the list.
  • Use initialized list, if you are not sure about the size and use TrimExcess() if memory is of your concern.

I would further like to study the List<T> class in detail since it is one collection that I use the most. In the mean time, if you are further interested in application performance, then look at the link http://msdn.microsoft.com/en-us/library/ms998574.aspx#scalenetchapt13_topic5

Update

I just came across the following points in MSDN.

How to choose between arrays and collections

Arrays are the fastest of all collection types, so unless you need special functionalities like dynamic extension of the collection, sorting, and searching, you should use arrays. If you need a collection type, choose the most appropriate type based on your functionality requirements to avoid performance penalties.

  • Use ArrayList to store custom object types and particularly when the data changes frequently and you perform frequent insert and delete operations. Avoid using ArrayList for storing strings.
  • Use a StringCollection to store strings.
  • Use a Hashtable to store a large number of records and to store data that may or may not change frequently. Use Hashtable for frequently queried data such as product catalogs where a product ID is the key.
  • Use a HybridDictionary to store frequently queried data when you expect the number of records to be low most of the time with occasional increases in size.
  • Use a ListDictionary to store small amounts of data (fewer than 10 items).
  • Use a NameValueCollection to store strings of key-value pairs in a presorted order. Use this type for data that changes frequently where you need to insert and delete items regularly and where you need to cache items for fast retrieval.
  • Use a Queue when you need to access data sequentially (first in is first out) based on priority.
  • Use a Stack in scenarios where you need to process items in a last–in, first-out manner.
  • Use a SortedList for fast object retrieval using an index or key. However, avoid using a SortedList for large data changes because the cost of inserting the large amount of data is high. For large data changes, use an ArrayList and then sort it by calling the Sort method.

The link : http://msdn.microsoft.com/en-us/library/ms998530.aspx

Why do I find Hashtable slow?

I re-conducted my experiment using Hashtable as a list (key and value) would be the same! It is dead slow, I repeat very-very slow - 1000 times slower than using an array and 80 times slower than the slowest list (un-initialized, added items witout using AddRange). But the guidelines states that Hashtable should be used to store large number of records. Is it really?

Relatively HashSet<int> was much faster. It was atleast 10 times faster to say the least. Note that you cannot use HashSet<int> instead of List<int> (since List<int> is obviously faster) because HashSet does not allow duplicate elements and is designed for high performance set operations. May not be a great test that one should really trust, but I feel simple collections are what used most of the times, so next time I would retest using objects instead of data types. My test results.

image
Ht - Hashtable and HS - HashSet<int>

From now on, I make it a point to use initialized List<int> since its performance is close to int[] and yet it is dynamic in nature. I hope not to use HashSet unless I have extremely complicated Set operations. I would use HashSet if (time taken to create HashSet + time taken to perform set operations) is less than (time taken to create a List + time taken to perform set operations using LINQ).

Performance is an interesting topic and the more you dig into it, the more knowledgeable you become about a system.

Thursday, November 13, 2008

Changing IIS Settings programmatically with code in C#

The IIS Server maintains a number of Application Pools and each application pool can host one or more web applications. The application pool settings could be altered through IIS Manager (inetmgr). But it would be nice if one could change certain settings from the application pool through C# code. Shown below is the code to change the IdleTimeout for an application pool.

string
metabasePath ="IIS://localhost/W3SVC/AppPools";
stringappPoolName ="Classic .NET AppPool";
DirectoryEntry apppools =
newDirectoryEntry(metabasePath);
//This throws an exception - AccessViolationException
//DirectoryEntry poolOfInterest =  apppools.Children.Find
(appPoolName);
foreach (DirectoryEntry p inapppools.Children)
{
if(p.Name == appPoolName)
{
   Console.WriteLine(p.Name);
   Console.WriteLine(p.InvokeGet(
"IdleTimeout").ToString());
   p.InvokeSet(
"IdleTimeout",new object[] {2});
   Console.WriteLine(p.InvokeGet(
"IdleTimeout").ToString());
   p.CommitChanges();
  
break;
}
}

Session timeout - Web.config settings are not good enough.
Web Apps that needs to run for long durations under a user identity would face Session timeout issues eventually. I had a situation where the web application I work on was dying out after a while. The users who logged into the system are logged out after 20+ minutes. I thought this has to do with Session getting expired and so I made a change in the sessionState.timeout property in the web.config. But sounds like it is not good enough. The problem was not fixed and I decided I would debug the problem using Visual Studio. But I noticed the debugger no longer breaks after the session has died off. This stuck to me that the pool to which the debugger is attached to is no longer running and there might be a setting for Application Pool which tells the timeout. Then I found the IdleTimeout setting inside Application Pool defaults. The above is shown the code that you can use to change this value. Boom! works like magic.

Tuesday, November 04, 2008

MSDN Question on WPF: Moving child window along with parent window

I noticed quiet a few people have this requirement where a popped up window has to move along with the parent window. This could be done pretty easily, thanks to the data binding features of WPF. Though this post does not handle pop ups' in wpf, the idea could easily be extended to them. The idea is to bind the Left and Top parameters of the Window (child) to those of its parent.

The following shows a window named "ParentWindow" which has a button when clicked launches a "ChildWindow".

<Window x:Class="XamlDemystified.ParentWindow"   xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Window3" Height="300" Width="300" Name="w"
>
<
StackPanel DataContext="{Binding ElementName=w}"
>
<
Button Click="Button_Click">Show</Button
>
</
StackPanel
>
</
Window>

The DataContext of the StackPanel is set the window instance itself, that too within the XAML.This has nothing to do with the current implementation but I wanted to shown how to set datacontext to the current instance of the window from XAML, instead of doing it from the C# code. If you have read my previous posts, you can notice that I usually set the DataContext from code-behind. Anyway, the Button_Click is shown below.

private void Button_Click(object sender, RoutedEventArgs e)
{
ChildWindow cW = new ChildWindow();
cW.Owner = this;
cW.Show();
cW.DataContext = this;
}

The event handler for the button click creates a new ChildWindow, sets its Owner as well as the DataContext to that of the parent. And there are different ways to do this, but I chose to do it the simplest way. The ChildWindow is shown below.




<Window x:Class="XamlDemystified.ChildWindow"    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Window4
" Height="100" Width="100"
Left="{Binding Left}"
Top="{Binding Top}"
Name="e"
>
<
Grid
>
<
Label Content="{Binding Left}"
/>
</
Grid
>
</
Window>


The child window contains a label that constantly displays the Left of the parent.



The solution is not fool-proof. It has certain limitations, the major one being the binding breaks when you move the child window. For this to work, you cannot move the child window manually. This could easily be fixed by handling the LocationChanged event and re-binding the Left and Top elements. If you do this, you also need to use a flag to determine if the LocationChanged was triggered by binding, in which case you ignore or if the user movement has caused this. I have not bothered to show the code, but if you do not get the idea, feel free to post it on MSDN Social forums for WPF or post a comment on this post. This being said, the ChildWindow size has to be less than that of the ParentWindow so that you can move the parent without having to touch the child window.



Alternatively, if you set initial position of the child window, then you can use the same idea to relatively set the Left and Top of the child. You might also want to take a look at the WindowStartupLocation enumeration on the Window class.

Monday, October 27, 2008

MSDN Question on WPF: How to decrease font-size automatically so that it fits completely inside a label?

Problem
I came across an interesting question on WPF forums. A user has a fixed size label which text can be very large. But since the size of the label is fixed, the text gets truncated which he does not want. The user wanted to automatically decrease the font-size such that it fits into the label completely.
Solution
One solution is to write some code to determine the available space and based on the space available use FormattedText and set the text dynamically. But I devised an easier solution.
There is a container in WPF called ViewBox which automatically scales the content inside such that it fits into the space completely. The idea is to use this ViewBox inside the template of the Label. The XAML code that does this is shown.

<Label Width="200" Height="300" Content="This is a very long text that you would be using to set the control text">
<
Label.Template>
<
ControlTemplate>
<
Viewbox>
<
ContentPresenter
Content="{TemplateBinding Property=ContentControl.Content}" />
</
Viewbox>
</
ControlTemplate>
</
Label.Template>
</
Label>

Now, when you run an application hosting such a label, the screenshots are shown.


image


The same application with much longer text is shown below.


image 
Hope this would be helpful to many!

Friday, October 24, 2008

Visual Tree Helper Methods

Shown below are two useful methods that works on a VisualTreeHelper class and makes it easy to access elements that are otherwise not easy to access. I would show you concrete examples to use it later, but for now here is the code for the two methods.

   1: public List<T> GetChildrenOfType<T>(DependencyObject parent) where T : DependencyObject


   2: {


   3:    List<T> list = new List<T>();


   4:    int childCount = VisualTreeHelper.GetChildrenCount(parent);


   5:    for (int i = 0; i < childCount; i++)


   6:    {


   7:        DependencyObject child = VisualTreeHelper.GetChild(parent, i);


   8:        //get the current child                 


   9:        if (child is T) list.Add((T)child);


  10:        //if it is of type that you are looking for, then add it to the list        


  11:        list.AddRange(GetChildrenOfType<T>(child)); // on that get a list of children that it has.            


  12:    } 


  13:    return list;



The above method can be used to search for any UIElement given its parent as a parameter. For example, GetChildrenOfType<Button>(StackPanel1) returns a list of all buttons hosted inside the StackPanel. A cut down version of this method is where it just returns the first item.



   1: public T GetChild<T>(DependencyObject parent) where T : DependencyObject


   2: {


   3:     //if(parent is Label) return parent;             


   4:     int childCount = VisualTreeHelper.GetChildrenCount(parent);


   5:     for (int i = 0; i < childCount; i++)


   6:     {


   7:         DependencyObject child = VisualTreeHelper.GetChild(parent, i);


   8:         if (child is T) return (T)child;


   9:         T childLabel = GetChild<T>(child);


  10:         if (childLabel != null) return childLabel;


  11:     } return default(T);


  12: }



The method is again easy to use.





So where did I use these methods? Working with TreeView?





How do I expand a TreeView completely?

This not a straight-forward issue since we know that most of the UI in WPF is virtualized unless otherwise specified. So I have a tree view and I would to completely expand the list. So how do I do it? What are the issues? If you set the TreeView IsExpanded property to true, it only expands the first level of children. So we need to repeat the process again on the children of the just appeared children. But they are not in the Visual Tree unless the lay out is updated. The method shown below works great to toggle expand/collapse of a tree view.









   1: private void ToggleButton_Click(object sender, RoutedEventArgs e)        


   2: {            


   3:          ToggleExpandCollapse(tvQueries); //start toggling with the parent.        


   4: }        


   5:  


   6: private void ToggleExpandCollapse(DependencyObject dO)        


   7: {           


   8:            foreach (TreeViewItem ti in GetChildrenOfType<TreeViewItem>(dO))            


   9:            {             


  10:                ti.IsExpanded = !ti.IsExpanded; //toggle expanded property.            


  11:                // update the layout such that Visual Tree gets updated       


  12:                tvQueries.UpdateLayout(); 


  13:                //now repeat the toggling on the current TreeViewItem            


  14:                ToggleExpandCollapse(ti);               


  15:            }       


  16: } 



Update


Bea just posted a simpler way to do this.






   1: <Style TargetType="TreeViewItem"> 


   2:           <Setter Property="IsExpanded" Value="True" /> 


   3: </Style>