Search This Blog

Thursday, March 31, 2011

Workflow Instance Terminate vs Abort

As we know we have two ways to cancel the workflow instance execution and remove it from memory. But we have to decide which one to select according to the scenario wa have, I am explaining the same below:


Wofkflow.Abort:

The workflow instance is aborted in a synchronous manner; that is, the method returns after the workflow instance has been aborted. The workflow runtime engine invalidates the workflow instance in memory and clears the WorkBatch. If a persistence service was used by your workflow instance, all work performed since the last persistence point is thrown away. After it aborts the workflow instance, the workflow runtime engine raises the WorkflowAborted event. You can call GetWorkflow to reload the workflow instance and start from its last persistence point. Here we can see that the last persistence informations will be kept in tables and is not cleared completely and there is a chance to reload.


Workflow.Terminate:

Abort is different from Terminate in that while Abort simply clears the in-memory workflow instance and can be restarted from the last persistence point, Terminate clears the in-memory workflow instance and informs the persistence service that the instance has been cleared from memory. For the SqlWorkflowPersistenceService, this means that all state information for that workflow instance is deleted from the database upon termination. You will not be able to reload the workflow instance from a previously stored persistence point.

Monday, March 28, 2011

Thread.Interrupt Vs Thread.Abort

You can stop a thread while it is executing with the Interrupt method. This causes the thread to throw a ThreadInterruptedException exception.This exception can then be handled inside a catch clause to free up resources if necessary.

A thread may also be aborted. The Abort method will cause the thread to throw a ThreadAbortException exception. This exception can not be handled in a catch block, but code contained in the finally block will execute and can be used to clean up. I mean to say that the code block coming after catch wont get executed in the case if abort exception because it will automatically be raised again at the end of the catch block. When this exception is raised, the runtime executes all the finally blocks before ending the thread. To avoid this automatic exception raising we can call Thread.ResetAbort to cancel the abort, from the catch block .


   1:  public static void DoWork() {
   2:          try {
   3:              for(int i=0; i<100; i++) {
   4:                  Console.WriteLine("Thread - working."); 
   5:                  Thread.Sleep(100);
   6:              }
   7:          }
   8:          catch(ThreadAbortException e) {
   9:              Console.WriteLine("Thread - caught ThreadAbortException - resetting.");
  10:              Console.WriteLine("Exception message: {0}", e.Message);
  11:              Thread.ResetAbort();
  12:          }
  13:          Console.WriteLine("Thread - still alive and working."); 
  14:          Thread.Sleep(1000);
  15:          Console.WriteLine("Thread - finished working.");
  16:      }

Friday, March 25, 2011

Working with null values in the .NET Framework

One of the interesting aspect of application development is handling null/zero/non existing/non allocated values. We can say like "our code is expecting some value for a variable but it got nothing or some unexpected value" and this is the places where we have use proper null checking to make the system stable.


Null - The Most Common
A null value is a value that doesn't refer toany object. It's the default value of reference-type variables.
    1:  struct sTest
   2:  {
   3:      public string teststring;
   4:  }    
   5:   
   6:  sTest obj = new sTest();
   7:  if (obj.teststring == null) {
   8:  Console.WriteLine("sTest is Null")
9: }
}
This code works without any problems with C#,but,VB.NET uses the Nothing keyword. The following code demonstrate its use:
   1:  Dim sTest As String
   2:  If (sTest Is Nothing) Then
   3:  Console.WriteLine("sTest is Null")
   4:  End If
Another area of confusion stems from the factthat VB.NET doesn't treat null and Nothing as equals; consequently,a VB.NET programmer may have to check for both values.
Microsoft provides a uniform method for working with null values: The base System.Convert namespace includes the DBNull object.
DBNull
The use of the DBNull class indicates the absence of a known value. While the Microsoft documentation says it's typically in a database application, you may also use it withany type of data.
In database applications, a null object is avalid value for a field. This class differentiates between a null value (a null object) and an uninitialized value (the DBNull.Value instance). For example, a table can have records with uninitialized fields. By default, these uninitialized fields have the DBNullvalue.
You can utilize the DBNull object by way of its Value property. This represents a null value, which is never equal to anything. The following C# snippet revises the previous example to utilize the DBNull class:
   1:  if (sTest.Equals(System.DBNull.Value)) {
   2:  Console.WriteLine("sTest is null.");

same code, like this:
If (sTest.Equals(System.DBNull.Value) Then
Console.WriteLine("sTest is Null")
End If
You may also use the DBNull.Value constant on the right-hand of an assignment operation, thus storing a null value within a reference type. In addition, the .NET Frameworkprovides the IsDBNull function (in the System.Convert namespace),which is a shorthand approach for determining if a reference type contains a null value. The following VB.NET uses IsDBNull to checkan object's value:
   1:  Dim oTest As Object = DBNull.Value
   2:  If ((IsDBNull(oTest))) Then
   3:  Console.WriteLine("oTest is Null")
   4:  End If
Even if you check for null values at every conceivable location within your code, they still may creep into the application. So you have to provide the try/catch exception block; it allows you to catch any unhandled exceptions that null values cause. The System namespace provides the NullReferenceException for these situations.
   1:  try {
   2:   
   3:  if (sTest.Equals(System.DBNull.Value)) {
   4:  Console.WriteLine("sTest is null.");
   5:  }
   6:   
   7:  } catch (System.NullReferenceException e) {
   8:  Console.WriteLine("Error: " + e.ToString());
9: }Handle your data with care
So now you have a uniform mechanism for checking any uninitialized references in your application.......

Sunday, March 20, 2011

Quick Journey through EnterprIse library Application Blocks

Summary : The Microsoft Enterprise Library ( part of Microsoft patterns and design )is a collection of reusable software components (application blocks) designed to assist software developers with common enterprise development cross-cutting concerns (such as logging, validation, data access, exception handling, and many others).

The Enterprise Library consists of the following seven Application Blocks.

· Data Access Application Block

· Exception Handling Application Block

· Logging and Instrumentation Application Block

· Security Application Block

· Cryptography Application Block

· Caching Application Block

· Configuration Management Application Block

Figure 1 Enterprise Library's Application Blocks

The following sections discusses each of these blocks briefly.

Data Access Application Block

ADO.Net Vs Data Access Block : Data Access Application Block is that application code can refer to particular databases by an ADO.NET connection string name, such as "Customer" or "Inventory." The application code can specify a named instance of a database and pass this parameter to theDatabaseFactory.CreateDatabase method. Each named database has its connection information stored in a configuration file. By changing the settings in the configuration file, developers can use their applications with different database configurations without recompiling their code.

Scenarios: Here I am explaining some key scenarios in which we can make use of DAAB. For all the scenarios , it is assumed that you already done neccessary configuration changes database creation.

1. DataReader : In this scenario, you want to retrieve multiple rows from a database and display them immediately and only once with a Web browser. You do not want to explicitly cache the data, manipulate it by using a DataSet object, or pass it to other components within your application. You simply want to use the results as quickly as possible.

These goals can be summarized as follows:

  • You want to retrieve data for read-only purposes, which, in most cases, means that you want to display the data.
  • You want to bind to a Web Form control for display.
  • You do not need to cache the data. After it is used, it is discarded.
   1:  Database db = DatabaseFactory.CreateDatabase();
   2:   
   3:  using (IDataReader reader = db.ExecuteReader(CommandType.Text, "Select Name, Address, City From Customers" ))
   4:  {
   5:    customerGrid.DataSource = dataReader;
   6:    customerGrid.DataBind();
   7:  }
2. DataSet : In a multi-tier system, you may need to pass data from a data access component to a middle-tier business component. The data is retrieved from the database and sent back, through the data access layer, to the business layer. The information is contained in the DataSet object.

   1:  Database db = DatabaseFactory.CreateDatabase();
   2:   
   3:  string sql = "GetProductsByCategory";
   4:  DbCommand cmd = db.GetStoredProcCommand(sql);
   5:   
   6:  // Retrieve products from category 7.
   7:  int category = 7;
   8:  db.AddInParameter(cmd, "CategoryID", DbType.Int32, category);
   9:   
  10:  DataSet productDataSet = db.ExecuteDataSet(cmd); 
3. ExecuteNonQuery : A common database task is to retrieve specific, multiple-column values. For example, in a Web-based online retail application, you may want to retrieve full product details for a certain product in response to a user request.
   1:  Database db = DatabaseFactory.CreateDatabase();
   2:   
   3:  string sql = "GetProductDetails";
   4:  DbCommand cmd = db.GetStoredProcCommand(sql);
   5:   
   6:  db.AddInParameter(cmd, "ProductID", DbType.Int32, 3);
   7:  db.AddOutParameter(cmd, "ProductName", DbType.String, 50);
   8:  db.AddOutParameter(cmd, "UnitPrice", DbType.Currency, 8);
   9:   
  10:  db.ExecuteNonQuery(cmd);
  11:   
  12:  string results = string.Format(CultureInfo.CurrentCulture, "{0}, {1}, {2:C} ",
  13:    db.GetParameterValue(cmd, "ProductID"),
  14:    db.GetParameterValue(cmd, "ProductName"),
  15:    db.GetParameterValue(cmd, "UnitPrice"));

3. ExecuteScalar : There are many situations in which you have to perform a single-item lookup.
   1:  Database db = DatabaseFactory.CreateDatabase();
   2:   
   3:  string sql = "GetProductName";
   4:  int productId = 7;
   5:  DbCommand cmd = db.GetStoredProcCommand(sql,  productId);
   6:   
   7:  string productName = (string)db.ExecuteScalar(cmd);

4. ExecuteNonQuery for multiple updates : There are many situations in which you have to perform a single-item lookup.When an application executes multiple operations against a database, a common requirement is that all of the operations must succeed or the database must roll back to its original state (that is, its state before the operations began).
   1:  public bool Transfer(int transactionAmount, int sourceAccount, int destinationAccount)
   2:  {
   3:    bool result = false;
   4:   
   5:    // Create the database object, using the default database service. The
   6:    // default database service is determined through configuration.
   7:    Database db = DatabaseFactory.CreateDatabase();
   8:   
   9:    // Two operations: one to credit an account and one to debit another account.
  10:    string sql = "CreditAccount";
  11:    DbCommand creditCommand = db.GetStoredProcCommand(sql);
  12:   
  13:    db.AddInParameter(creditCommand, "AccountID", DbType.Int32, sourceAccount);
  14:    db.AddInParameter(creditCommand, "Amount", DbType.Int32, transactionAmount);
  15:   
  16:    sql = "DebitAccount";
  17:    DbCommand debitCommand = db.GetStoredProcCommand(sql);
  18:   
  19:    db.AddInParameter(debitCommand, "AccountID", DbType.Int32, destinationAccount);
  20:    db.AddInParameter(debitCommand, "Amount", DbType.Int32, transactionAmount);
  21:   
  22:    using (DbConnection conn = db.CreateConnection())
  23:    {
  24:      conn.Open();
  25:      DbTransaction trans = conn.BeginTransaction();
  26:   
  27:      try
  28:      {
  29:        // Credit the first account.
  30:        db.ExecuteNonQuery(creditCommand, trans);
  31:        // Debit the second account.
  32:        db.ExecuteNonQuery(debitCommand, trans);
  33:   
  34:        // Commit the transaction.
  35:        trans.Commit();
  36:   
  37:        result = true;
  38:      }
  39:      catch
  40:      {
  41:        // Roll back the transaction. 
  42:        trans.Rollback();
  43:      }
  44:      conn.Close();
  45:   
  46:      return result;
  47:    }
  48:  } 
5. DataSet to update database : The goal in this scenario is to transfer data stored in a DataSet object to the database. 
   1:  Database db = DatabaseFactory.CreateDatabase();
   2:   
   3:  DataSet productsDataSet = new DataSet();
   4:   
   5:  string sql = "Select Select ProductID, ProductName, CategoryID, UnitPrice, LastUpdate From Products";
   6:  DbCommand cmd = db.GetSqlStringCommand(sql);
   7:   
   8:  string productsTable = "Products";
   9:   
  10:  // Retrieve the initial data.
  11:  db.LoadDataSet(cmd, productsDataSet, productsTable);
  12:   
  13:  // Get the table that will be modified.
  14:  DataTable dTable = productsDataSet.Tables[productsTable];
  15:   
  16:  // Add a new product to existing DataSet.
  17:  DataRow addedRow = dTable.Rows.Add(new object[] {DBNull.Value, "New product", 11, 25});
  18:   
  19:  // Modify an existing product.
  20:  dTable.Rows[0]["ProductName"] = "Modified product";
  21:   
  22:  // Establish the Insert, Delete, and Update commands.
  23:  DbCommand insertCommand = db.GetStoredProcCommand("AddProduct");
  24:  db.AddInParameter(insertCommand, "ProductName", DbType.String, "ProductName", DataRowVersion.Current);
  25:  db.AddInParameter(insertCommand, "CategoryID", DbType.Int32, "CategoryID", DataRowVersion.Current);
  26:  db.AddInParameter(insertCommand, "UnitPrice", DbType.Currency, "UnitPrice", DataRowVersion.Current);
  27:   
  28:  DbCommand deleteCommand = db.GetStoredProcCommand("DeleteProduct");
  29:  db.AddInParameter(deleteCommand , "ProductID", DbType.Int32, "ProductID", DataRowVersion.Current);
  30:   
  31:  DbCommand updateCommand = db.GetStoredProcCommand("UpdateProduct");
  32:  db.AddInParameter(updateCommand, "ProductID", DbType.Int32, "ProductID", DataRowVersion.Current);
  33:  db.AddInParameter(updateCommand, "ProductName", DbType.String, "ProductName", DataRowVersion.Current);
  34:  db.AddInParameter(updateCommand, "LastUpdate", DbType.DateTime, "LastUpdate", DataRowVersion.Current);
  35:   
  36:  // Submit the DataSet, capturing the number of rows that were affected.
  37:  int rowsAffected = db.UpdateDataSet(productsDataSet, "Products", insertCommand, updateCommand, deleteCommand,
  38:                      Microsoft.Practices.EnterpriseLibrary.Data.UpdateBehavior.Standard);

Exception Handling Application Block

An exception is an error that occurs at runtime. If the same is not handled by your code, it might lead to premature termination of the flow of execution of your application. Exceptions should be handled very carefully as handling them are quite expensive and too many exception blocks in your code might lead to poor application performance. The Patterns and Practices group from Microsoft has introduced the Exception Handling Application Block with the sole purpose of providing the application developers with a set of the best practices and strategies that should be followed for handling exceptions in the code. The salient features of the Exception Handling Application Block include:

· Encapsulates the recommended best practices on handling exceptions

· Support for logging exceptions

· Extensibility

· Ease of use

Logging and Instrumentation Application Block

Efficient Logging and Instrumentation feature in an enterprise application development phase facilitates application performance monitoring. Hence, it is a very important feature in enterprise application software development. The Patterns and Practices group from Microsoft has come up with this powerful block that can be instrumental in the above stated situations. The salient features of the Logging and Instrumentation Application Block include:

· Support for logging synchronously and asynchronously

· Support for formatters

· Support for logging to different destinations

Security Application Block

The Security Application Block from the Patterns and Practices group of Microsoft facilitates the implementation of security features in enterprise applications built on top of the Microsoft .NET framework. The salient features of the Security Application Block include:

· Support for authentication and authorization

· Supports both role and profile management

· Plug ability with the Data Access Application Block

· Plug ability with the Cryptography Application Block

Cryptography Application Block

The Cryptography Application Block is a collection of reusable and extensible code that simplifies the usage of cryptographic functionality in applications that are designed on the Microsoft.NET framework. The salient features of the Cryptography Application Block include:

· Plug ability

· Configurable

· Extensible

Caching Application Block

Caching is an important feature that promotes improvement of application performance by storing the frequently used pages or data in main memory. The Caching Application Block from the Patterns and Practices group of Microsoft encapsulates efficient, consistent caching strategies and, hence, simplifies implementation of caching strategies in enterprise application development. The salient features of the Caching Application Block include:

· Support for efficient caching strategies in web applications

· Configurable

· Thread Safety

Configuration Management Application Block

The Configuration Management Application Block from the Patterns and Practices group of Microsoft provides, "a seamless integration with configuration sources other than XML files. You could use the registry, a database, or many other storage mediums, all using a common interface to manipulate the configuration information." The salient features of the Configuration Management Application Block include:

· Support for reading and writing the configuration data

· Support for storing configuration data at multiple locations

· Support for caching the configuration data

· Plug ability


Thanks!

_mkrs_