Thursday 31 July 2008

A Concurrent Programming Primer on Code Project

 

I found a good read on PLINQ (Parallel LINQ) and TPL (Task Parallel Library) on code project. It doesn’t cover everything though but gives you good examples and common pitfalls using them.

The examples cover,

  • Parallel Class - Parallel.For, Parallel.Do, AsParallel  constructs
  • Exception Handling for Parallel programming constructs
  • Handling of compiler side-effects.

You need the TPL CTP download and of course VS 2008 for trying out the samples.

Converting a LINQ query from sequential to parallel execution is as simple and straightforward as below :

   1: Enumerable<T> data = ...;



   2: var q = from x in data.AsParallel() where p(x) orderby k(x) select f(x);




Here’s the link

Friday 25 July 2008

Designing an Enumerator for Business Objects

Following is my elegant enumerator design which can be used for enumerating business objects from the database. Designing an enumerator with C#, .Net 3.5 will be much more elegant simply because of LINQ and LINQ to SQL. I will write about it in my future posts. LINQ has made it extremely easy to do such things, and i will prove my point in the future posts. This is also mostly based on Enterprise patterns (Check out the most famous Martin Fowler's book) . I've used a Table Gateway and a normal Iterator pattern.

BusinessObjectEnumerator

 

Product - Business Object

Product.cs

public class Product
{
int id;

public int Id {
get {
return id;
}
set {
id = value;
}
}
string name;

public string Name {
get {
return name;
}
set {
name = value;
}
}
double price;

public double Price {
get {
return price;
}
set {
price = value;
}
}

public override bool Equals(object obj) {
if (null==obj)
return false;
else
{
Product p = obj as Product;
return (p.id == this.id);
}
}

public override int GetHashCode() {
return id.GetHashCode();
}

public override string ToString() {
return name.ToString();
}



 



DBEnumerator.cs



    public abstract class DBEnumerator<T>:IEnumerator,IEnumerable
{
private int position;
protected List<T> list;
protected TableGateway tablegateway;
protected abstract void Read(string sql);
public virtual void Add(T item) {
if (!list.Contains(item))
{
list.Add(item);
}
}

#region IEnumerable Members

public IEnumerator GetEnumerator() {
return (IEnumerator)this;
}

#endregion

#region IEnumerator Members

public object Current {
get {
return (object)list[position];
}
}

public bool MoveNext() {
position++;
return (position < list.Count);
}

public void Reset() {
position = -1;
}

#endregion
}



ProductEnumerator.cs



    public class ProductEnumerator:DBEnumerator<Product>
{
public ProductEnumerator(string sql) {
this.tablegateway = new TableGateway();
this.list = new List<Product>();
Read(sql);
this.Reset();
}

internal TableGateway TableGateway {
get {
return tablegateway;
}
}

protected override void Read(string sql) {
DataTable dt = new DataTable();
dt = tablegateway.ExecuteNonQuery(sql);
foreach (DataRow row in dt.Rows)
{
Product p = new Product();
p.Id = Convert.ToInt32(row["Id"].ToString());
p.Name = row["Name"].ToString();
p.Price = Convert.ToDouble(row["Price"].ToString());
Add(p);
}
}
}



TableGateway.cs



   public class TableGateway
{
private string connstring;
private IDbCommand command;
private Collection<IDataParameter> parameters;

public TableGateway() {
connstring = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:\\Projects\\C#Projects"+
"\\BusinessObjectEnumerator\\Inventory.mdb;";
parameters = new Collection<IDataParameter>();
}

public void AddParameters(string parameterName, string parameterValue) {
IDataParameter param = command.CreateParameter();
param.ParameterName = parameterName;
param.Value = parameterValue;
}


public string TableName{
get {return "Tablegateway";}
}

public DataTable ExecuteNonQuery(string sql)
{
using (IDbConnection conn = GetConnection())
{
command = conn.CreateCommand();
foreach (IDataParameter param in parameters){
command.Parameters.Add(param);
}

OleDbDataAdapter oledbdataadapter = new OleDbDataAdapter(sql,(OleDbConnection) conn);
DataSet dataset = new DataSet();
try
{
oledbdataadapter.Fill(dataset, this.TableName);
}
catch
{
throw;

}
finally
{
conn.Close();
}
return dataset.Tables[TableName];
}
}

private IDbConnection GetConnection() {
return new OleDbConnection(connstring);
}

}



Putting the ProductEnumerator to test



  static void Main(string[] args) {

ProductEnumerator myproducts = new ProductEnumerator ("select * from products");

Console.WriteLine("Enumerating products..\n");

foreach (Product p in myproducts){
Console.WriteLine("ID: ,"+p.Id+
"Name: ,"+ p.Name+
"Price: ,"+p.Price);
}

Console.WriteLine("\nPress any key to exit..");
Console.ReadKey();
}



Notice, Since we have implemented the IEnumerable and IEnumerator interfaces, we can use the ProductEnumerator in a foreach statement. This will be the cool part of Enumerators. The MSIL generation for the foreach statement would do something like the following:



IEnumerator ienum = myproducts.GetEnumerator();



while(ienum.MoveNext()) {



...



}



Also, We can  provide mechanisms to add stuff into the List<T> of the DBEnumerator. By doing this we will need to have some mechanisms to persist the newly added object to the DB. In other words instantaneously serialize the object. This will require some kind of an EventHandler to track the List<T> added event. Hmm... reminds me of a 1000 patterns from Martin Fowler , just to do this.. :) (Oh, my brave attempt to write a DataMapper in 3 days, i paid the price in the ACW..Thanks to Dr.Grey for enlightening me about my deed)



Output



Enumerating products..



ID: ,1Name: ,Product APrice: ,10.99

ID: ,2Name: ,Product BPrice: ,12.99


ID: ,3Name: ,Product CPrice: ,10.99


ID: ,4Name: ,Product DPrice: ,14.99


ID: ,5Name: ,Product EPrice: ,19


ID: ,6Name: ,Product FPrice: ,19.99


ID: ,7Name: ,Product GPrice: ,7.99


ID: ,8Name: ,Product HPrice: ,5.45


ID: ,9Name: ,Product IPrice: ,3.44


ID: ,10Name: ,Product JPrice: ,0.99



Press any key to exit..



The DB (for proof)



image



Tuesday 22 July 2008

Next Gen Static Analysis of Code

I came across this white paper illustrating the next generation static analysis of code using boolean satisfiability (SAT). This is an interesting read. It tells you how to use SAT in static analysis to improve code quality and security by identifying a greater number of critical defects in the code with lowest rate of false-positive results.

The white paper can be found here.

Monday 21 July 2008

Capabilities of MS Silverlight!!

Check out the Hardrock memorabilia site, to truly see Silverlight in action.

Uncommon sense

Some good 'gyan' on how to

1. Price software

2. Licence software

3. Manage upgrades

VSTS Tips and Tricks

I came across this wonderful blog post detailing some cool tips and tricks using VSTS like Managed Code Analysis (FXCop), adding Check-in policies, Team System for Architects,Developers and Testers, TFS quick configurations , Setting up a load testing lab etc. All in all it's a nice read up on VSTS. The link to this article can be found here.

Wednesday 2 July 2008

Running Queries on Multi-Core Processors


Multi-core processors are here. Once pervasive mainly in servers and desktop PCs, now multi-core processors are being used in mobile phones and PDAs, resulting in great benefits in power consumption. Responding to the increased availability of multi-processor platforms, Parallel Language Integrated Query (PLINQ) offers an easy way to take advantage of parallel hardware, including traditional multi-processor computers and the newer wave of multi-core processors.
PLINQ is a query execution engine that accepts any LINQ-to-Objects or LINQ-to-XML query and automatically utilizes multiple processors or cores for execution when they are available. The change in programming model is tiny, meaning you don't need to be a concurrency guru to use it. In fact, threads and locks won't even come up unless you really want to dive under the hood to understand how it all works. PLINQ is a key component of Parallel FX, the next generation of concurrency support in the Microsoft® .NET Framework.
Using technologies like PLINQ will become increasingly crucial to ensuring the scalability of software on future parallel microprocessor architectures. By utilizing LINQ at choice places throughout your applications today—such as where you have data- or compute-intensive operations that can be expressed as queries—you will ensure that those fragments of your programs continue to perform better when PLINQ becomes available and the machines running your application grow from 2 to 4 to 32 processors and beyond. And even if you only run that code on a single-processor machine, the overhead of PLINQ is typically so small that you won't notice a difference. In addition, the data parallel nature of PLINQ ensures your programs will continue to scale as the size of your data sets increases.
More here