Wednesday 23 September 2009

Multi-threading with the help of Extension method

I love Extension methods!

For people who work with multi-threaded windows forms application, it's common to write code like this:

public void BindNewLoginList(object logins)
{
if (dgvLogins.InvokeRequired)
{
dgvLogins.BeginInvoke((System.Threading.ThreadStart)delegate()
{
BindNewLoginList(logins);
});
return;
}
dgvLogins.DataSource = logins;
}
But with the new extension feature of .Net Framework, I can create a method like this:
public static void ThreadSafeInvoke(this System.Windows.Forms.Control control, System.Threading.ThreadStart method)
{
if (control.InvokeRequired)
control.BeginInvoke(method);
else
method.DynamicInvoke();
}
Now, I simply call this method from any windows control, and it will take care of checking of the caller and invoke the method accordingly. How nice and neat it is!
public void BindNewLoginList(object logins)
{
dgvLogins.ThreadSafeInvoke(() => dgvLogins.DataSource = logins);
}

Thursday 6 August 2009

SQL: A recursive query for a self-reference table

I was working with a self-reference table and wanted to query the parent-child relationship.



Say, given an ExceptionRepositoryId, I want to display all its children. After a little while I came up with a recursive SQL:
DECLARE @parentId int
SET @parentId = 210;

WITH TEMP (ExceptionRepositoryId, ParentExceptionRepositoryId)
AS
(
SELECT
ExceptionRepositoryId, ParentExceptionRepositoryId
FROM
dbo.tbl_ExceptionRepository
WHERE
ExceptionRepositoryId = @parentId
UNION ALL
SELECT
t1.ExceptionRepositoryId, t1.ParentExceptionRepositoryId
FROM
dbo.tbl_ExceptionRepository t1
inner join TEMP t2 ON t1.ParentExceptionRepositoryId = t2.ExceptionRepositoryId
)
SELECT * FROM TEMP
And I am happy to get the results like the following:

Friday 31 July 2009

Entity Framework: Error 2048 when using custom stored procedures

I was trying to map my custom stored procedures to Insert/Update/Delete functions on the Entity Framework model designer. After hitting the "Save" button, I got 2 error messages like the following:

Error 2048: The entity set '[set name]' includes function mappings for association set '[fk name]', but none exists in element 'DeleteFunction' for type '[entity type name]'. Association sets must be consistently mapped for all operations.

I was confused, why do I need to have association mapping in the delete function? After a bit of searching and digging, here are the findings.

First, let's have a look at the two Entity models in question.

I have a 1-to-many relationship from left to right between ExceptionSource and ExceptionRepository. Besides, there is a self reference 1-to-many relationship on ExceptionRepository.

To avoid the mapping error 2048 , in my ExceptionRepository delete stored procedure, I have to include the two FKs ExceptionSourceId and InnerExceptionRepositoryId. Even though I don't really need to use these two keys in the delete stored procedure.



To conclude, if you want to map custom stored procedures to Entity functions:
1) you must map all Insert/Update/Delete functions.
2) include the FKs in the delete function if any defined in the source table.

Friday 24 July 2009

Switched back from my other blog...

Ported all the old work related posts from the other blog I have.

I think I'll stick to this one from now on...

Catch unhandled exceptions in Windows Forms applications

The company I am working for has developed a Windows Forms application Framework. New applications are developed as plug-ins to this Framework. Our team is looking at catching all unhandled exceptions globally and log all these exceptions in a central repository.

After spending a little time on MSDN, I found this very helpful piece of information.

To handle all UI thread exceptions, the .Net Framework provides Application.ThreadException.To handle all non-UI thread exceptions, AppDomain.CurrentDomain.UnhandledException.

One thing worth noting is that UnhandledException won't prevent the application from terminating. But before the application terminates, you are given a chance to log the error or display some custom message to the users. And that's what I am looking for.

Here is the sample code from the MSDN article.
// Starts the application. 
[SecurityPermission(SecurityAction.Demand, Flags = SecurityPermissionFlag.ControlAppDomain)]
public
static void Main(string[] args)
{
// Add the event handler for handling UI thread exceptions to the event.
Application.ThreadException +=
new
ThreadExceptionEventHandler(ErrorHandlerForm.Form1_UIThreadException);

// Set the unhandled exception mode to force all Windows Forms errors to go through our handler.
Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException);

// Add the event handler for handling non-UI thread exceptions to the event.
AppDomain.CurrentDomain.UnhandledException +=
new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException);

// Runs the application.
Application.Run(new ErrorHandlerForm());
}

SSIS: Retrieve data from Recordset Destination

Some times when developing a SSIS package, it is handy to import data into an in-memory Recordset instead of a file or a database table.

However SSIS doesn't provide out of box support for reading data from a Recordset. A little workaround is required to make this working.

First, define a user variable of type "object".
Then map the varaible with the Recordset Destination object.



The last step is to drag a Script task onto the Control flow. Put the following code in the script and you are blessed with a DataTable object.

Dim dt As New Data.DataTable
Dim adapter As New Data.OleDb.OleDbDataAdapter
If Dts.Variables.Contains("RGRecordset") Then
adapter.Fill(dt, Dts.Variables("RGRecordset").Value)
End If

SSIS: Import multiple Excel files into database with Foreach Loop Container

I wanted to import more than 60 Excel files into a database table the other day. Foreach Loop Container really helped to perform the task.

I started with creating an Excel Connection Manager. I hard coded the file path to make the BI designer happy. Then in the Properties window of the Excel Connection Manager, I set the “ExcelFilePath” and/or “Server” to the value of the pre-defined user variable. I probably only need to set “ExcelFilePath”, but anyway I just wanted to make these values consistent.



Then I dragged a Foreach Loop container onto the Control Flow. From the Properties window of a Foreach Loop Container:
1) Foreach File Enumerator.
2) Hard coded the Folder path to please the designer, and set the file mask and the return value.
3) Added an Expression so that the value of “Directory” is actually set by a user variable I defined earlier. One thing that bugs me a litter is – it is called “Folder” on the screen but ‘Directory” in the Expressions list.



4) In the Variable Mappings section, I set the return value to the user variable.



Now I could drag a Data Flow Task into the Foreach Loop Container, and load data from an Excel file to a database table. Of course the Excel Data Source uses the Excel Connection Manager I created in the first step.

To make the life in the multithreaded world easier 2

As I mentioned in my To make the life in the multithreaded world easier 1, I kept writing code as below to check the "InvokeRequired" property to check if the method is invoked from a worker thread or the main thread.
private void DoSomethingFunction()
{
if(this.InvokeRequired)
{
this.BeginInvoke((System.Threading.ThreadStart)delegate()
{
DoSomethingFunction();
});
return;
}
// Do something here
}
After doing the check again and again, I started to ask myself - is there a way to abstract it a bit so that I don't need to repeat myself?

And this is what I come up with - a class acts as a smart agent:
Public class AsyncCall
{
public static void AutoBeginInvoke(System.Windows.Forms.Control targetControl, Delegate targetMethod)
{
if (targetControl.InvokeRequired)
targetControl.BeginInvoke(targetMethod);
else
targetMethod.DynamicInvoke(null);
}
}
This method checks to see if this method is invoked from a worker thread or from the main thread where the windows control is created, and invoke the method accordingly.

Our DoSomethingFunction() can be rewritten as:
private void DoSomethingFunction()
{
AsyncCall.AutoBeginInvoke(this, (System.Threading.ThreadStart)delegate(){// Do something here});
}
Let's have a more concrete example, say I want to update a textbox or a label in a thread safe way, in the past, I have to do things like this:
private void UpdateTextBox()
{
if(textBox1.InvokeRequired)
{
textBox1.BeginInvoke((System.Threading.ThreadStart)delegate()
{
UpdateTextBox();
});
return;
}
textBox1.Text = "Update test";
}

private void UpdateLabel()
{
if(lbl1.InvokeRequired)
{
lbl1.BeginInvoke((System.Threading.ThreadStart)delegate()
{
UpdateLabel();
});
return;
}

lbl1.Text = "Update test";
}
Now I simply call:
private void UpdateTextBox()
{
AsyncCall.AutoBeginInvoke(textBox1, (System.Threading.ThreadStart)delegate(){textBox1.Text = "Update test"});
}

private void UpdateLabel()
{
AsyncCall.AutoBeginInvoke(lbl1, (System.Threading.ThreadStart)delegate(){lbl1.Text = "Update test"});
}
Some people may want to separate the anonymous part
(System.Threading.ThreadStart)delegate(){ //do update}
into a different method.But I found it quite nice and neat here.

What if I want to pass parameters to my update method? Then some delegate accepting parameters have to be created.

You can have a delegate defined as this:

public delegate void SomeDelegate(string args);

Then add a new method in AsyncCall class:
public static void AutoBeginInvoke(System.Windows.Forms.Control targetControl, SomeDelegate targetMethod, string args)
{
if (targetControl.InvokeRequired)
targetControl.BeginInvoke(targetMethod, args);
else
targetMethod.DynamicInvoke(args);
}
This is your new UpdateTextBox method:
private void UpdateTextBox()
{
AsyncCall.AutoBeginInvoke(textBox1, (SomeDelegate)delegate(string args){textBox1.Text = args;}, "update test");
}
What if I want to do a search, and after getting the search result back I want to do something else.

Normally, we would have:
public ILIst delegate SomeSearchDelegate();

private IList Search()
{
IList result = null;

// Do search here...

return result;
}

private void OnSearchCompleted(IAsyncResult ar)
{
SomeSearchDelegate del = ar.AsyncState as SomeSearchDelegate;

IList result = del.EndInvoke(ar);

// Do some post search processing...
}

private void SomeSearchMethod()
{
SomeSearchDelegate del = new SomeSearchDelegate(Search);
del.BeginInvoke(OnSearchCompleted, del);
}
To do the task using AsyncCall class, we can define another method in the AsyncCall class:
public static void AutoBeginInvoke(SomeSearchDelegate targetMethod, AsyncCallback callbackMethod)
{
targetMethod.BeginInvoke(callbackMethod, targetMethod);
}
So the SomeSearchMethod() can be rewritten as:
private void SomeSearchMethod()
{
AsyncCall.AutoBeginInvoke(
(SomeSearchDelegate)delegate()
{
IList result = null;
// Do search here...
return result;
},
(AsyncCallback)delegate(IAsyncResult ar)
{
SomeSearchDelegate del = ar.AsyncState as SomeSearchDelegate;
IList result = del.EndInvoke(ar);
// Do some post search processing...
});
}

Hope what discussed above is not as clear as mud to the readers ;)...

To make the life in the multithreaded world easier 1

I haven't done any serious windows forms development till this recent 6 months. Prior to that, I may have done some small desktop tools here and there, but they are in no means serious enough. Most of my work in the past were Asp.Net, MOSS, SQL Server... but no Windows forms applications.

In my recent windows application development work, I came across a lot of code like this:

private void DoSomethingFunction()
{
if(this.InvokeRequired)
{
this.BeginInvoke((System.Threading.ThreadStart)delegate()
{
DoSomethingFunction();
});
return;
}

// Do something here
}
"this" in the code snippet is normally some windows forms control or user control. In .Net Framework 2, cross-thread accessing to a windows forms control is not allowed. So if you have some multi-threading code, you'll need to check the "InvokeRequired" property to determine if this method is invoked by a worker thread or the main thread, and do things appropriately for the two scenarios.

But there is this "hidden" issue with "InvokeRequired", which is not documented. After we have this application deployed to UAT, the testers reported that sometimes (most of the time it's when they first launched the application), if they didn't wait for a few seconds, but click straight to the left hand side navigation node to open a tab window, the application simply went hanged.

This was an issue of intermittent nature and hard to re-produce this in the developer's machine. I studied the code again and again and couldn't see anything wrong.

Luckily I found this very good article "Mysterious Hang or The Great Deception of InvokeRequired" at http://ikriv.com:8765/en/prog/info/dotnet/MysteriousHang.html. This nice guy presented a thorough case study on why your .Net 2 multithreaded UI may hang from time to time.

This issue is related to the fact that .Net defers the creation of real win32 window as much as possible due to performance consideration. The window handle will be created when the control needs to be actually shown on screen or when the control.handle is requested programatically. Before a real window handle gets created (rarely but due to some race condition), the control.InvokeRequired may return a deceptive value (it always returns false in that case), and the calls from a non-GUI worker thread to the GUI might cause some unexpected behaviour.

Back to our application, when the tab form is loading, we have worker threads to do things asynchronously to make the UI more responsive to the end users. When the async work is done, the worker thread will then try to update the UI and that's when the "InvokeRequired" property is checked. However, as mentioned above, at that time if the win32 handle for our tab form hasn't been created at all, the mysterious hang will kick in. Mystery solved!

The quick fix is when registering the view (the windows control) with the controller (MVC pattern), call the control.Handle programatically before firing up any async calls.