Friday, January 25, 2008

Locking Objects And Base Types

If you have a class that can be accessed with multiple threads you will need to wrap any outside access to private level variables with a lock statement. See Figure 1.0 where we have a customer class and a process class with a customer inside.

Figure 1.0

public class Customer
{
private int _customerId;
private string _customerName;

public int CustomerId
{
get {return _customerId; }
set {_customerId = value; }
}
}

public class Process
{
private IList _customersToProcess;

public IList CustomersToProcess
{
get
{
lock(_customersToProcess)
{
return _customersToProcess;
}
}
set
{
lock(_customersToProcess)
{
_customersToProcess = value;
}
}
}
}


The lock statement only takes objects. In order to lock base types, you must declare them as objects and then initialize them with their base type. When you do this, the object will default similar to what happens with VB.NET. Booleans will default to false, and integers to 0, and DateTime to MinValue. Strings can be locked without using boxing and unboxing from an object type since they are already objects. When in the getter the object must be cast back into the base type. Take a look at the Figure 1.1 below.

Figure 1.1

public class Customer
{
private int _customerId;
private string _customerName;

public int CustomerId
{
get {return _customerId; }
set {_customerId = value; }
}
}

public class Process
{
private object _numberOfThreads= new int();
private IList _customersToProcess;

public int NumberOfThreads
{
get
{
lock (_numberOfThreads)
{
return (int) _numberOfThreads;
}
}
set
{
_numberOfThreads= value;
}
}

public IList CustomersToProcess
{
get
{
lock(_customersToProcess)
{
return _customersToProcess;
}
}
set
{
lock(_customersToProcess)
{
_customersToProcess = value;
}
}
}
}


The example above is for illustrative purposes only. In a later post we will talk about using events to do custom progress information.

Why TDD is bad

TDD (Test Driven Development) refers to creating an individual test first and then creating the code for that test. This is opposite of creating code and then at some later date, creating unit tests. Proponents of TDD claim that it promotes looser coupling and better code coverage. I agree that junior level developers would benefit from this; however for senior level developers it simply creates unnecessary work. I find that it is easier to create loosely coupled methods in a domain class and then simply generate the tests for those methods using a tool such as NUnit Test Generator. After the tests are generated, single tests can be run against the corresponding method in the domain class. Without code generation for unit tests, the developer has to manually create the unit tests, since the code does not exist yet. That is just about as fun as manually creating NHibernate mappings.




NUnit Test Generator is a great way to quickly create unit tests for NUnit, csUnit, MbUnit, or Microsoft Unit Tests. It does things like min/max/null testing too. Simple interface but powerful output.



The reason why TDD works well for junior level developers is that they tend to forget to write the unit tests at all. When you write the tests first, you can never forget to write them. However senior developers are used to checking the code coverage with tools such as NCover and TestMatrix. It can't be any more obvious, the untested areas of your code are highlighted in red. Another way to ensure that tests are being written is to set up a code coverage threshold on your continuous integration server. Cruise Control .NET can be set up to automatically fail when the code coverage falls below the threshold.





TestMatrix is a great testing tool that is integrated right into Visual Studio. It has a test runner, captures performance, and performs detailed code coverage. It is like a Swiss army knife, I wouldn't be surprised if the next version tested for cancer. I like it better than what is built into Microsoft Team Suite.


Below is an example of how TestMatrix highlights code slightly different than NCover. The covered areas are in green, the uncovered areas in red. The little yellow progress bars indicate the largest performance hit for particular lines. In the example below we see that logging the error is slightly more expensive than throwing it again.




When it comes down to it, your client wants the highest quality code at the lowest price. They could really care less if you wrote the tests first or the code first. A good way to blow money and time on your project is to write your unit tests manually. If you are on a fixed bid enterprise project, this can mean the difference between success and failure. I have seen it first hand.

Having unit tests with good code coverage ensures reliability but it does not ensure maintainability. You can still have a junior developer do TDD and create crap code. The only way around this is to do paired programming or code review.

Which ever way you choose to do your tests, creating the tests first, or creating the code first; you should always write them. There is no excuse for legacy projects that do not have tests. They should be created at the first opportunity. Unit test generation solves the problem to generate tests for legacy code and speeds along the process for new projects. To all of my fans, Q'apla! Which means success in Klingon.

Monday, October 29, 2007

Commodore 64 Beats Vista in Key Performance Metric

How could the venerable 1 Mhz Commodore 64 beat out the brand spanking new Vista OS which requires hardware of at least a Ghz? The C64 beats Windows hands down when it comes to boot time. Yes, of course the C64 OS is on a chip so that is why you can literally turn on the computer and you are up and running. Even if you use the Hibernate mode in Windows, Vista startup time is not instantaneous.

It is time to put Windows on Flash RAM

Flash RAM has really come down in pricing. It would be great if we could have instant boot time again. We could stick the OS Flash RAM chip, mabye an SD card in a special slot in the front of the PC. When we need to migrate PCs, we simply plug it into the front of the new PC. The chip could be password protected with a GUID so as to prevent theft.

I guess the alternative is to put the flux capacitor (from Back to the Future) in the PC so it can start booting before we need it. A good application would be a giant RV going 88 MPH.

Friday, October 26, 2007

Things I wish I knew about Microsoft Access before I started using Microsoft Access

Microsoft Access is one of the most powerful databases for small business available on the market. Not only does it have its own form and reporting development environment built in; the wizards and design views allow the user to quickly create data centered applications. This ease of use, coupled with the simple fact that Access is included with Microsoft Office has lead to widespread usage in both the small business and corporate environments.

I have worked with Access for several years. In my experience, I have come to several conclusions about Access:

Multi-User Company Wide Applications should never be built using Microsoft Access.
Multi-User applications in Access use the file locking system built into Windows. What this means is that after the first user connects to the database, there is a significant slowdown in performance. MS Access supports up to 256 connections, the actual performance limit is much lower. I have seen access applications come to a crawl with only 10 users. Instead use SQL Server with a .NET front end.

Set the Focus On The Field
One of the painful things you must do in MS Access when doing applications is that you must set the focus on the field before you can get the value the user typed in.

MS Access Corrupts Databases
Because of the file locking and users disconnecting due to lockups in Windows, MS Access Databases will sometimes become corrupted. Try these things if it happens to you:


  1. Do a repair and compact.

  2. Restore from your backup. If you don’t have a backup, you need to back up your database nightly.

  3. Create a blank database and import it in.

  4. Buy a tool that repairs access databases.


Easy Applications Are Super Easy, Hard Applications are Super Hard
Access tends to be incredible at building quick and dirty database applications. If there are a significant amount of business rules involved, Microsoft Access simply becomes counterproductive. It is easier to build a business rule intensive application in .NET than to build it in Microsoft Access.

So what is Microsoft Access good for?

  • Microsoft Access is great when you have a bunch of spreadsheets that you need to import and run some reports on.

  • Microsoft Access is great to store simple things at home like your recipes or DVD collection.

  • • Microsoft Access is great for small business until the business is ready to afford a full time dedicated IT person to do .NET development.



Finally, get yourself an Access Database Comparison Tool, you make copies of your Access Database, employees will change things and then you will wonder what changed. The best tool for comparing Access Databases is AccessDiff.