Thursday, January 18, 2007

Automatic Properties Issue On Structs

In general, class objects are allocated on the heap while structs are created on the stack, reference vs. value for short. Their syntax is almost identical, but I found one issue using struct today. Following C# code doesn't compile in Visual Studio 2005:
    struct GeoCode
{
public double Longitude { get; set; }
public double Latitude { get; set; }

public GeoCode(double longitude, double latitude)
{
this.Longitude = longitude;
this.Latitude = latitude;
}
}
The error is:

Backing field for automatically implemented property 'Program.GeoCode.Latitude' must be fully assigned before control is returned to the caller. Consider calling the default constructor from a constructor initializer ...

And:
The 'this' object cannot be used before all of its fields are assigned to ...
It's okay with:
    struct GeoCode
{
public double Longitude;
public double Latitude;

public GeoCode(double longitude, double latitude)
{
this.Longitude = longitude;
this.Latitude = latitude;
}
}
Sounds like the issue of automatic properties on structs in .NET 2.0. To fix it, just follow the error description "Consider calling the default constructor from a constructor..":
    struct GeoCode
{
public double Longitude { get; set; }
public double Latitude { get; set; }

public GeoCode(double longitude, double latitude) : this()
{
this.Longitude = longitude;
this.Latitude = latitude;
}
}

Friday, January 05, 2007

A tricky int i=0; i=i++; i = ? question

I was asked a question that sounds simple but it's a bit tricky. What's the output of following C# code?
public class Program
{
static void Main(string[] args)
{
int i = 0; i = i++;
int j = 0; j = ++j;
Console.WriteLine("{0} {1}", i, j);
Console.Read();
}
}
I thought it's "1 1" but I was wrong. The correct answer is "0 1".

Why? i++ is an after operation, so a temporary value is created to store the before and after value. The explanation is not that straightforward. Let's look at the IL code generated by compiler, and see what's under the hood:
.method private hidebysig static void  Main(string[] args) cil managed
{
.entrypoint
// Code size 47 (0x2f)
.maxstack 3
.locals init (int32 V_0,
int32 V_1)
IL_0000: nop

// i operation
IL_0001: ldc.i4.0 // Put constant number 0 onto the stack
IL_0002: stloc.0 // Pop from the stack and store it in the local variable #0 (number = 0)
IL_0003: ldloc.0 // Push local variable #0 onto the stack
IL_0004: dup // Duplicate the value in the stack (push another 0 onto stack)
IL_0005: ldc.i4.1 // Put constant number 1 onto the stack
IL_0006: add // Pop last two values from stack and push back their sum (1+0=1)
IL_0007: stloc.0 // Pop from stack and store it to local variable #0 (number=1)
IL_0008: stloc.0 // Pop from stack and store it to local variable #0 (overwritten number=0)

// j operation
IL_0009: ldc.i4.0 // put constant number 0 onto the stack
IL_000a: stloc.1 // Pop from the stack and store it in the local variable #1 (number=0)
IL_000b: ldloc.1 // Push local variable #1 onto the stack
IL_000c: ldc.i4.1 // Put constant number 1 on the stack
IL_000d: add // Pop last two values from stack and push back their sum (1+0=1)
IL_000e: dup // Duplicate the value in the stack (push another 1 onto stack)
IL_000f: stloc.1 // Pop from the stack and store it to local variable #1 (number=1)
IL_0010: stloc.1 // Pop from the stack and store it to local variable #1 (number=1)

// Print
IL_0011: ldstr "{0} {1}"
IL_0016: ldloc.0 // Load local variable #0 (0) onto stack
IL_0017: box [mscorlib]System.Int32
IL_001c: ldloc.1 // Load local variable #1 (1) onto stack
IL_001d: box [mscorlib]System.Int32
IL_0022: call void [mscorlib]System.Console::WriteLine(string,
object,
object)
IL_0027: nop
IL_0028: call int32 [mscorlib]System.Console::Read()
IL_002d: pop
IL_002e: ret
} // end of method Program1::Main
We can see that the plus operation is run in a separate stack, the result of 1 is assigned to the local variable, but is overwritten by original value of 0. Thus the original i value of 0 is used for the assignment of i = i++. Is it ambiguous? I'm not sure. It's the way how .NET deals with such scenarios.

(Updated Jan 7, 07) I tested in Java (1.5) and got the same result of "0 1". But in C++ (compiled by VS.NET 2005) it returns "1 1".

Tuesday, November 21, 2006

Passing Multiple-value With XML In SQL Server 2005

The XML functions has been improved a lot in SQL Server 2005. Suppose there's a simple Contacts table:
Contacts(Name varchar(100), Phone varchar(100), Email varchar(100))
The application is sending following XML data to SQL Server for Contacts update (simply string type for ADO.NET parameter):
<Contacts>
<Contact>
<Name>Name ABC</Name>
<Phone>111-222-3333</Phone>
<Email>abc@abc.com</Email>
</Contact>
<Contact>
<Name>Name BCD</Name>
<Phone>222-333-4444</Phone>
<Email>bcd@bcd.com</Email>
</Contact>
</Contacts>
The stored procedure takes the XML as parameter and parse it internally:
CREATE PROCEDURE [dbo].[Update_ContactsByXml]
(
@Contacts xml
)
AS
BEGIN
SET NOCOUNT ON
-- Create a temp table to hold the values
declare @tmpItems table
(
Name varchar(100),
Phone varchar(100),
Email varchar(100)
)
-- Insert all Ids to temp table
INSERT INTO @tmpItems
SELECT TMPXML.Nodes.value('./Name[1]', 'varchar(100)') as Name,
TMPXML.Nodes.value('./Phone[1]', 'varchar(100)') as Phone,
TMPXML.Nodes.value('./Email[1]', 'varchar(100)') as Email
FROM @Contacts.nodes('//Contacts/Contact') TMPXML (Nodes)

-- Update existing contacts
UPDATE C SET Phone = T.Phone, Email = T.Email
FROM @tmpItems T INNER JOIN Contacts C ON T.Name = C.Name

-- Insert new contacts
INSERT INTO Contacts
SELECT * FROM @tmpItems WHERE Name NOT IN (SELECT Name FROM Contacts)
END
One advantage of using XML to pass multi-value is that it's not vulnerable to SQL injection attack.

Tuesday, November 07, 2006

A Few Releases

After long time of Beta the final release date of Java 6 (1.6) is confirmed to be released next month, which is a big news for Java community. In the Linux world, Fedora Core 6 was released last month, and its previous version Fedora Core 5 was released less than 7-month ago. Fedora looks like trying to catch up the installation/UI improvement brought by Ubuntu, who announced latest 6.10 release two weeks ago.

I used to work with C/Java in Unix/Linux, but most of my work in recent years is with Microsoft solutions, .NET and C# specifically. Now I pay more attention on MS technologies. So what's new in Microsoft world? Well Microsoft has long product lines, and new releases or updates are just too frequent: Team Foundation Server (TFS) 2006, BizTalk 2006, Office 2007, Windows Server 2008, etc...

What else? Microsoft has just released .NET 3.0 and announced the completion of SharePoint 2007 RTM today!

What's new in .NET 3.0? Mainly four components are added and Microsoft named them foundations:
  • Windows Presentation Foundation (WPF): a new user interface subsystem and API based on XML and vector graphics, which uses 3D computer graphics hardware and Direct3D technologies.
  • Windows Communication Foundation (WCF): a service-oriented messaging system which allows programs to interoperate locally or remotely similar to web services.
  • Windows Workflow Foundation (WF): a workflow engine for task automation and integrated transactions.
  • Windows CardSpace: a component securely storing a person's digital identities and provides a unified interface for choosing the identity for a particular transaction, such as logging in to a website.
What's the SharePoint 2007? SharePoint 2007 includes a free version of Windows SharePoint Services (WSS) 3.0, and a not free (actually quite expensive) product called Microsoft Office SharePoint Server (MOSS) 2007. MOSS 2007 is built on top of WSS 3.0 and offers many features that are not included in WSS 3.0.

I happen to have a chance to take some BizTalk 2006/SharePoint 2007 courses during the past 6 months. The course materials were based on the SharePoint 2007 Beta. I am very impressive of how SharePoint technologies can help a business to streamline line their process. Common IT tasks in company, such as creating/editing pages, adding/configuring web parts, configuring people permissions, document management, team collaborations, etc., now can be easily done by business people without IT guys' assistance.

Well you would say, what about developers and IT specialists? In this radically changing world, we need to learn more and more, right? True. New releases and new products indicate changes and new stuff. Change can be scary and you have to face it. But no matter C, Java or C#, Windows or Linux, your existing skills can transition in new technologies in some forms. Those fancy technologies and buzz words can be easily adopted since you have the fundamental of understanding how the computer world works. People living in this world all face too much information, especially in IT world. It would be great if we could filter all information around us efficiently.

Is there a course of "IT 101 - How To Avoid Being Overwhelmed" in school?

Sunday, October 15, 2006

.NET TableAdapters Inside TransactionScope

Both TableAdapter and TransactionScope are new in .NET 2.0. Auto-generated TableAdapter and DataTable could play an ORM (Object-relational Mapping) role and act as DAL (Data Access Layer) in an application. TransactionScope wraps the complexity of transaction, and it allows you to put DB interactions inside a transactional block. Using TableAdapter and TransactionScope properly can significantly simplify developers work.

I have just read an article Managing Transactions using TransactionScope that provides an example of using TableAdapter and TransactionScope together:
public static int AddDepartmentWithEmployees(Department dept)
{
int res = 0;

DepartmentAdapter deptAdapter = new DepartmentAdapter();
EmployeeAdapter empAdapter = new EmployeeAdapter();
using (TransactionScope txScope = new TransactionScope())
{
res += deptAdapter.Insert(dept.DepartmentName);
//Custom method made to return Department ID after inserting the department "Identity Column"
dept.DepartmentID = deptAdapter.GetInsertReturnValue();
foreach(Employee emp in dept.Employees)
{

emp.EmployeeDeptID = dept.DepartmentID;
res += empAdapter.Insert(emp.EmployeeName, emp.EmployeeDeptID);
}
txScope.Complete();
}
return res;
}
The code demos using TableAdapter and TransactionScope to insert a Department record and a collection of Employee records in that department into database, presuming SQL Server 2005 in this case to take advantage of lightweight transaction.

Looks really great and simple. But there's an issue of such implementation: Distributed Transaction Coordinator (DTC) is promoted at run time to complete this transaction. A run time error page will show up if DTC is not properly setup in the server; even with DTC configured, overhead of DTC would introduce big performance issues.

The reason is that each TableAdapter maintains its own database connection, and multiple operations with the same TableAdapter would lead to multiple database connections. A lightweight transaction is used in TransactionScope by default with SQL Server 2005, but DTC is promoted if multiple connections exist inside the same TransactionScope, which is the case in the above example.

We all know the cost of DTC is too expensive. Thus it's recommended to avoid using TableAdapters with TransactionScope, or avoid letting TableAdapters to manage the connections. You should manually and explicitly maintain all connections that are involved in a transaction scope if you have to use them together.

Wednesday, October 04, 2006

.NET Object Construction Sequence


How's a .NET object constructed and what's the order of initialization of object fields & static fields? Let's do a simple test:

class Program
{
static void Main()
{
new SubClass();
Console.Read();
}

class BaseClass
{
Logging baseField = new Logging("BaseClass field initializer");
static Logging baseStaticField = new Logging("BaseClass static field initializer");

static BaseClass()
{
Logging.Write("BaseClass static constructor");
}

public BaseClass()
{
Logging.Write("BaseClass constructor");
}
}
class SubClass : BaseClass
{
Logging subClassield = new Logging("SubClass field initializer");
static Logging subClassStaticField = new Logging("SubClass static field initializer");

static SubClass()
{
Logging.Write("SubClass static constructor");
}

public SubClass()
{
Logging.Write("SubClass constructor");
}
}

class Logging
{
static int count = 1;
public Logging(string info)
{
Write(info);
}

public static void Write(string info)
{
Console.WriteLine("{0}: {1}", count++, info);
}
}
}
Result:

1: SubClass static field initializer
2: SubClass static constructor
3: SubClass field initializer
4: BaseClass static field initializer
5: BaseClass static constructor
6: BaseClass field initializer
7: BaseClass constructor
8: SubClass constructor
The result shows a few interesting things:
1. Derived class field initializer first and base class field initializer next.
2. Class field initializer first and class constructor next.
3. Base class constructor first and derived class constructor next.
4. Static field initializer first and static constructor next.
5. Static constructor first and class constructor next.
5. Derived class static constructor first and base class static constructor next.

What's the reason for such order? Class constructor would reference those fields or static fields thus those fields must be initialized before the class constructor; same as static fields need to be initialized before the static constructor; on the other hand, base class constructor runs before derived class constructor because subclass construction may depend on the the state initialized by the base class, and base class usually has no knowledge about the subclass.

A common mistake is that a class field inialializer is using another non-static field, property or method. For example following code snippet will get compilation error:

public int GetTotalCount()
{
return Service.GetTotalCount();
}

// Compile error: "A field initializer cannot reference the non-static field, method, or property..."
private int _totalNum = GetTotalCount();

// Compile error: "An object reference is required for the non-static field, method, or property..."
static int _totalNum = GetTotalCount();
The easy way to resolve above problem would be making the static GetTotalCount method. You can also initialize the field inside the class constructor if you don't like the static approach.

Thursday, September 21, 2006

Observer Pattern In .NET

Observer pattern is a publish-subscribe pattern. It allows an object (observer) to watch another object (subject), and be notified when subject is changed.

Java has defined java.util.Observable class and java.util.Observer interface since SDK 1.0:
public class Observable extends Object
{
public void addObserver(Observer o) {}
public void deleteObserver(Observer o) {}
public void notifyObservers() {}
//...
}

public interface Observer
{
public void update(Observable o, Object arg){}
}
By inheriting Observable class and implementing Observer interface, the observer pattern is enforced. There's no Observer and Observable interface/class in .NET BCL. However it's not a difficult task to implement the observer pattern in .NET. Following code demos a simple .NET implementation of observer pattern:
using System;
using System.Text;
using System.Collections;
using System.Threading;

class Program
{
public interface IObserver
{
void Update(string state);
}

public interface IObservable
{
void AddObserver(IObserver o);
void NotifyObservers();
}

public class WeatherObservable : IObservable
{
private volatile int _temperature;
private ArrayList _observers = new ArrayList();
private Random rand = new Random();

public WeatherObservable()
{
new Thread(new ThreadStart(WeatherWatcher)).Start();
}

public void WeatherWatcher()
{
Console.WriteLine("Weather is changing ...");
while (true)
{
_temperature = rand.Next(-20, 40);
NotifyObservers();
Thread.Sleep(1000);
}
}

public void AddObserver(IObserver obj)
{
lock (_observers.SyncRoot)
{
_observers.Add(obj);
}
}

public void NotifyObservers()
{
lock (_observers.SyncRoot)
{
foreach (IObserver observer in _observers)
{
observer.Update(_temperature.ToString());
}
}
}
}

public class WeatherDisplayer : IObserver
{
public void Update(string state)
{
int temperature = int.Parse(state);
Console.WriteLine("Temperature now is {0}", temperature);
}
}

public class WeatherAlarm : IObserver
{
public void Update(string state)
{
int temperature = int.Parse(state);
if (temperature < -10)
{
Console.WriteLine("\nCold Alert! Temperature is {0}\n", temperature);
}
else if (temperature > 30)
{
Console.WriteLine("\nHot Alert! Temperature now is {0}\n", temperature);
}
}
}

static void Main(string[] args)
{
WeatherObservable ww = new WeatherObservable();
ww.AddObserver(new WeatherDisplayer());
ww.AddObserver(new WeatherAlarm());
Console.Read();
}
}
The WeatherObservable class simulates the weather changes, and keeps sending the updated temperatures to observers (subscriber). There are two subscribers in the demo code; one shows the latest temperature and the other shows alert information when temperature is in certain condition. When running the application, a console would look like:

The above code is just a clone of Java implementation. For concise demonstration purpose, not all functions are included and synchronized notification is used.

Actually .NET uses event concept to resolve the publish-subscribe problem. An observable subject publishes its events to its subscribers which registered those events by safe and typed functions (delegate). The implementation of observer pattern can be simplified by using .NET event:
using System;
using System.Text;
using System.Collections;
using System.Threading;

class Program
{
public class WeatherObservable
{
private volatile int _temperature;
Random rand = new Random();

public delegate void UpdateDelegate(int temperature);
public event UpdateDelegate TemperatureUpdateEvent;

public WeatherObservable()
{
new Thread(new ThreadStart(WeatherWatcher)).Start();
}

public void WeatherWatcher()
{
Console.WriteLine("Weather is changing ...");
while (true)
{
_temperature = rand.Next(-20, 40);

if (TemperatureUpdateEvent != null)
{
TemperatureUpdateEvent(_temperature);
}
Thread.Sleep(1000);
}
}
}

public class WeatherDisplayer
{
public void TemperatureUpdated(int temperature)
{
Console.WriteLine("Temperature now is {0}", temperature);
}
}

public class WeatherAlarm
{
public static void TemperatureUpdated(int temperature)
{
if (temperature < -10)
{
Console.WriteLine("\nCold Alert! Temperature is {0}\n", temperature);
}
else if (temperature > 30)
{
Console.WriteLine("\nHot Alert! Temperature now is {0}\n", temperature);
}
}
}

static void Main(string[] args)
{
WeatherObservable ww = new WeatherObservable();
WeatherDisplayer displayer = new WeatherDisplayer();
ww.TemperatureUpdateEvent += new WeatherObservable.UpdateDelegate(displayer.TemperatureUpdated);
ww.TemperatureUpdateEvent += new WeatherObservable.UpdateDelegate(WeatherAlarm.TemperatureUpdated);
Console.Read();
}
}
Note: as shown in the code, both class member functions or static functions can be registered to an event.

Tuesday, September 19, 2006

Simple iFrame Popup Window

<style type="text/css">
.popup {
        position:fixed;
        clear:both;
        height: 400px;
        width: 600px;
        z-index: 2;
        border: solid;
        background-color: white;
}
.grayBG {
        position: fixed;
        clear:both;
        top: 0px;
        left: 0px;
        right: 0px;
        bottom: 0px;
        overflow: hidden;
        padding: 0;
        margin: 0;
        background-color: #000;
        z-index: 1;
        filter:alpha(opacity=70);
        opacity:0.7;
        -moz-opacity:0.7;
}
</style>
<script language="javascript" type="text/javascript">
    function showDiv(id)
    {
        var div = document.getElementById("divPop");
        div.style.display = "block";
        var divFrame = document.getElementById("divFrame");
        divFrame.src = "PopupPage.aspx?id=" + id;        
        //document.body.style.scrolling = "no";
    }
    function hideDiv()
    {
        var div = document.getElementById("divPop");
        div.style.display = "none";
        //document.body.style.scrolling = "auto";
    } 
</script>
<div id="divPop" style="display: none;">
 <div class="grayBG" runat="server"></div>
 <div runat="server" class="popup">
    <a onclick="hideDiv();"></a><br />
    <iframe id="divFrame" runat="server" width="100%" height="100%">
    </iframe>
 </div>
</div>

Sunday, August 13, 2006

HPCBench Now Supports Linux Kernel 2.6.X

I just updated the HPCBench utility last week. It now can work in latest Linux distributions with kernel 2.6.x.

You can visit http://hpcbench.sourceforge.net for more information about HPCBench.

Saturday, August 05, 2006

Replacing Tokenized String Using Regular Expression In .NET

using System;
using System.Collections.Generic;
using System.Text.RegularExpressions;

class Program
{
static void Main(string[] args)
{
string text = "Contact name:$NAME$, address:$ADDRESS$, phone:$PHONE$, email:$EMAIL$...";
Dictionary<string, string> tokenDictionaries = new Dictionary<string, string>();
tokenDictionaries.Add("NAME", "Rob");
tokenDictionaries.Add("PHONE", "123456789");
tokenDictionaries.Add("EMAIL", "Rob@abc.com");
Console.WriteLine(ReplaceToken(text, tokenDictionaries));
Console.Read();
}

public static string ReplaceToken(string text, Dictionary<string, string> tokenDictionaries)
{
string pattern = @"\$.*?\$";
Match mc = Regex.Match(text, pattern);
if (mc.Success)
{
while (mc.Success)
{
if (!string.IsNullOrEmpty(mc.Value))
{
string tokenName = mc.Value.Substring(1, mc.Length - 2);
string tokenValue = string.Empty;
if (!string.IsNullOrEmpty(tokenName) && tokenDictionaries.ContainsKey(tokenName))
tokenValue = tokenDictionaries[tokenName];
text = text.Substring(0, mc.Index) + tokenValue + text.Substring(mc.Index + mc.Length);
mc = Regex.Match(text, pattern);
}
}
}
return text;
}
}
Result:
Contact name:Rob, address:, phone:123456789, email:Rob@abc.com...