#Google Analytic Tracker

Pages

Apr 16, 2009

My First Windows 7 Experience

For awhile, I had been avoiding of trying out new OS. Windows XP works so well that I rarely care about other OSs. Until last year, one of my colleges, who is more or less a Mac fanatic, talked me into getting a Mac.  After many months of indecision, I finally brought a MacBook Pro, and got to experience what is like to use a Mac.

Mac OS X has many nice features that I wish to see in XP, but at the same time, I struggled to understand some of the UI design  philosophies behind Mac OS X. I will talk about this concern in another time.

Of course, there is Windows Vista. Its bad reputations on the medias deter me from try it.  I tried it one time, and the UAC pops up for pretty much for everything I do. Even opening your Control Panel would require your permission.

This week, I got a rare opportunity learn about Windows 7 in a 3 days training session. Yes, this is for software developers! There are hand-on-labs to do and you get to try to do some programming with the Windows 7 features.

So far, I like Windows 7 beta a lot. Here are some of the things that I like.

  • Taskbar
  • Libraries and Federated Search
  • Background Services and Tasks

In addition, the session also covers Power Management, Multi-Touch and Ink, and the obvious the Windows Ribbon (Office Ribbon).

Snipping Tool

But first, I have to mention about this tool that I find in Windows 7 (Ultimate), the Snipping Tool.

image

This tool obviously does more than your typical “Alt-Print Screen”. You can do capture in these 4 modes:

  • Free-form snip – allow you to draw around an area
  • Rectangle snip – a rectangle screen capture
  • Windows snip – allow you to select a windows and do a screen capture on it
  • Full screen snip

In addition, you can draw and highlight the captured screenshot.

image

Taskbar

One major improvement that I find in Windows 7 compare with XP is the Taskbar

image

  • Icon display only, no text, it saves you space
  • Activate your program right from the task bar. There is no quick launch.
  • All related windows are hidden in a single program icon, it only shows the running and pinned programming.

So, how do you see your opened Windows? You can simple hover your mouse pointer over the executing program on the taskbar and it will display all it related windows in a thumbnail.

image

In terms of programming, you can dictate what you want to display.

Preview

The taskbar get even better, than you put your mouse on the program thumbnail, all the other windows will become glass, leaving only your selected window.

image

In addition, you can close your windows with the little red cross button on the preview screen.

Notice that if you have multiple windows open, you can see the icon look like a stack:

image

Other things including the following also make the taskbar attractive:

  • Thumbnail Toolbars
    image
  • Progress bar icon
    image
  • Jump List- right click on the icon
    image

The item in the Jump List and Thumbnail can be customized though Windows 7 API.

Ribbon

Ribbon from Office 2007 has comes to Windows7. Both Ribbons look very similar. My question is why not just rip the Ribbon out from Office.

Windows 7 Paint:

image

Windows 7 Word Pad:

image

Oh you can’t use Ribbon in Windows XP. Your application will not be able to run under XP if you have Windows Ribbon. For developers, this make our life a lot tougher. You either need have 2 different version of your program, or buy a third party ribbon that works in Windows XP.

Libraries

Another feature that I like is the Library feature. The concept is similar to Unix’s links. This is like a virtual folder where you can put whatever you want in it.

The idea is that you can use the library to “collect” other folders’ contents. For example, if I have a number of folders storing pictures, I can add these locations to the library and I can get a single view of all my pictures. This is similar to your Windows Media Player, or iTune where it scans all your music, videos and pictures into an organized folder view.

Libraries and Preview functions:

image

You can also create your own libraries:

image

One thing to note, my college and I have some concerns where the users may get confuse on how the folder system works. Note that if you delete the file from the library, it will delete it from your harddrive, which is not the same as a link.  We will have to wait out the public feel about this feature.

UAC

One thing I notice that that Windows 7 is not as annoying as Vista. UAC only shows up when I try to run program in administrative mode, or when I install new programs. Opening your Control Panel doesn’t need your UAC permission, yeah!

Boot Time

Another thing I should mention is Windows boot time significantly faster because:

Less start up background service – Service that not needed are removed.

Delayed Auto Start service – Service that doesn’t need to start at boot time.

Service can start up by Trigger – A service doesn’t start up unless an event occurs.

These strategies help Windows 7 Start up faster.

Software Development

I never do any COM and unmanaged programming (C++) in Windows. Fortunately, Windows 7 SDK will comes with managed code for me to do Windows 7 programming in C#.

However, this SDK is not the final product from Windows 7, so use it at your own risk. .NET 4.0 should include the API needed to program in Windows 7.

Conclusion

There is a lot I want to talk about Windows 7, but I will probably stop here for now.  In some ways, I feel that MS took a number of UI design idea from Apple.  However, if it works, why not use it.  One of the things I learn from the training is that programming in C++ (unmanaged) is a lot more troublesome compare with C# (managed). Am I glad I am working in C#!

Mar 13, 2009

The Data Binding, the Invoke, and the Deadlock

When it comes to Windows Application programming, there are a number of things to be considered.

  1. Data Binding – the ability for the windows control to automatically refresh its UI when the underlying data changes. This feature saves developer’s time from writing code to update the UI when the underlying data change.
  2. UI Thread Invoke – When an UI needs to be updated, the updating code has be execute by original thread that create the UI (i.e. UI Thread, or usually the Main Thread). For example:
private void OnDataRowChanged(DataRow oDataRow)
{
if (this.InvokeRequired)
{
this.Invoke(new OnDRChangedDelegate(OnDataRowChanged), oDataRow);
return;
}

//Do Your UI Update ...
}
  1. Deadlock – In a multiple threaded application, when thread A waiting to acquire a resource and never able to get it because thread B is holding this resource, while it is waiting for thread A to release its resource. You will end up having two threads waiting and your program hangs. This can happens for more than two threads locking each other resources.


    image

 

The Problem

In a multi-threaded application, there are many threads interacting with the application data. In my case, it is a DataSet. A DataSet is an ADO.NET (old) technology that acts like a in memory database. It contains tables, columns, constraints, relationships and etc. To ensure the program is thread safe, we have to lock the DataSet before modifying the data using the lock keyword in C#.

This all sounds good until we start doing data blinding. In my case, I have a number of grids (Infragistic UltraGrid) blinded to the DataSet. In the beginning, everything look great. Data are loaded by thread to the data model and grids automatically updated.

Here is the model that causes problem:

image

Each time when our server updates a piece of data to a client DateSet, it creates a .NET remoting thread (represent by the green), and update the DataSet. To ensure we are thread safe when updating the DataSet, we have a lock to prevent more than one thread updating (writing) the DataSet.

Unfortunately during QA, we occasionally see the UltraGrid display a big red X. The entire gird basically crashes and it no longer able to display data.  The exceptions we got includes NullReferenceException, IndexOutOfRangeException and etc.  Initially, we thought that was a Infragistic bug in the UltraGrid, but in the end, we realized it is another type of Cross Thread operation. For example: InvalidOperationException was unhandled (Cross-thread operation not valid: Control ‘XXX’ accessed from a thread other than the thread it was created on.)

To prevent cross thread operations, we decided to ensure we called the ISynchronizeInvoke.IsInvokeRequired when we updates the DataSet.

Revised model (Deadlock on Invoke and Lock DataSet):

image

For the first couple of runs, the application seems to be executing correctly using the revised model. However, we got the application to hang.

From the diagram, it is probably obvious  that there is a deadlock from the pictures. However, it isn’t obvious when the order of locking and invoking calls are in different modules.  Because we didn’t standardize how we should do Invoke call and lock the data set first, we end up having random deadlocks on the Invoke call, and at the lock statement block.

Where is the dead lock?

In case the diagram is not obvious to some of the readers, here is what happening. Assuming you have an UI Controls created by only one thread, called the UI Thread (Main Thread), when Thread 1 called ISynchronizeInvoke.Invoke(), the UI Thread is locked to execute the Thread 1 request. At the same time, Thread 2 has locked the DataSet which prevents other threads updating it. When the Main Thread try to lock DataSet, it has to wait for Thread 2 to exit the lock block. At the same time, Thread 2 is waiting for the UI Thread to complete so that it can do the Invoke(). Since 2 threads are waiting for each other resources, we have a dead lock.

Solving The Problem

This model may not be the best solution, but it is simple to understand and it works:

image

In this model, all I did is to ensure all threads call Invoke() before locking the DataSet.

This design ensures we only have one thread access to the Lock. In our case it is the UI Thread. Whenever called the Invoke() on a Windows Form, your execution is passed to the UI Thread.

Now, you may wonder, why do I still need to lock the DataSet when there the Invoke there there.  From this simplistic diagram, we don’t.

But, you may have N number of Threads that didn’t call the Invoke for whatever the reason. An application can be complicated. To be safe, always lock the DataSet before applying changes.

 

 

 

 

 

How to Find a Deadlock?

You probably don’t want to ship a software that hangs in front of your customs, so you want to find these deadlocks before your customers find them for you.  Well, there is no easy way to determine where are the deadlocks in your application. Here is a couple of suggestions that may help:

  • Peer Code Review – have someone double check your check before check in the code. Check for possible deadlock by examining where lock, monitor class, invoke class are used.
  • Use a Deadlock Monitor – using a custom locking mechanism to determine if there is a possible dead lock.
  • Have a lot of tests – this can be unit tests, integration tests and your manually user tests. Whenever you see the application stop responding, report it and try to solve it.

Find Your Dead Lock using VS.

If you do find your application stops responding, what can you do? First, determine if your application is actually “working” by checking its CPU usage. If it is around 100% for one of your core, your application may be working hard or got simply running an infinite loop. This is NOT a deadlock!

In this case, your best tool would be using Visual Studio! Assuming you have all the debug files (.pdb) and source code for your program:

  1. Debug->Attach To Process, and attach to your non-responding application.
  2. Click on the pause button or Debug->Break All to stop the application
  3. Debug->Windows->Threads

A deadlock usually happen between two threads that hold on two resources, so you need to check where your executing threads has stopped. In the following example, I have a number of threads running, but I am only concerning my owns. These are the last two items in the Threads grid below.

image

  1. Double click on the Main Thread and the Worker Thread to see their executing locations.

For example:

image Main Thread executing location

  1. Notice the “green” highlight represent were is your thread executing.
  2. If you hit F5 (run) to un-pause the thread, and hit pause again, your thread execute would most likely remind at the same place.

image Worker Thread executing location

So, at least we know these two threads are trying to get some resources. However, how can you tell if they are holding each other requesting resources?

In this example, we know that the Main Thread waiting, so the Worker Thread have to wait at the “this.Invoke()” line. However, how do you know if the Worker Thread lock the m_oDataModel?

The only way to find out is to trace the executing code through the call stack. (If someone have a better way to find a dead without going though the code, please let me know!!!)

  1. Double click on the Work Thread
  2. Debug->Windows-> Call Stack

image

By tracing through the stack, I soon discover that the one of the call stack got a lock on m_oDataModel. Luckily in my case, I only have 2 visible stacks for this thread. If you have more, you will have to walk though them.

image

Ah, from the above, I see that I called lock(m_oDataModel), follow by calling the AddDataWorker() method.

Once you find out there is a dead lock, you will have to resolve it. Either by fixing the order of the locks or provide a better architecture that prevent developers run into this situation.

Sample Deadlock Code

Sorry that I don’t have a web space to store code file. I can only post the source code as it is. In this example, I have a form that has one button. If you click on the button, a dead lock will occur.

public partial class Form1 : Form
{
private DataSet m_oDataModel = new DataSet();
public Form1()
{
InitializeComponent();
m_oDataModel.Tables.Add("MyTable");
m_oDataModel.Tables["MyTable"].Columns.Add("SomeKey");
m_oDataModel.Tables["MyTable"].Columns.Add("ItemName");
}

private void button1_Click(object sender, EventArgs e)
{
ThreadPool.QueueUserWorkItem(new WaitCallback(AddData));

//Similate doing something
Thread.Sleep(1000);

lock(m_oDataModel) //Wait for lock forever (deadlock)
{
m_oDataModel.Tables["MyTable"].
Rows.Add(Guid.NewGuid(), "Some Data");
}
}

private void AddData(object oState)
{
lock(m_oDataModel)
{
AddDataWorker();
}
}

private void AddDataWorker()
{
if (this.InvokeRequired)
{
//Wait for Main Thread to be free forever (deadlock)
this.Invoke(new Action(AddDataWorker));
return;
}

//Update a textbox
this.textBox1.Text = m_oDataModel.Tables["MyTable"].
Rows[0]["ItemName"].ToString();
}
}

Conclusion

As you get more experience and understand the structure of your application, the easier it will be for you to identify a deadlock. Deadlock isn’t just cause by the “lock” keyword in C#. It can be an Invoke() call, a read/write lock on a file, an database transaction lock and etc.  For those who read though the article to this end, thanks for reading and I hope this post helps you solving your deadlock issue.

Feb 18, 2009

Restore SQL Server Backup Database => Operating system error 5(Access is denied) using MS SQL Server Management Tool

Occasionally I have to backup a SQLServer database from one machine to other one. Many times I encounter this Access is denied error, and I always forgot why it happens. So, I decided to write the solution in this blog so that I can reference it back in the future.

Backing up the Database

  1. You need to have Microsoft SQL Server Management Studio. By the way, SQL2008 SQL Server Management Studio comes with intelliSense, it makes SQL writing much easier.
  2. Connect to your database, in Object Explorer windows, right click on the database->Tasks->Backup  
    SQL Management Screenshoot1.1
  3. Add  back destination. The location can only be your database local directory
  4. Select Back type to "Full", so that you can transport the database file to another database server.
  5. Click OK to complete the operation

Restoring

  1. Copy the backup file to your local machine that host your destination database server. SQLServer somehow limited restore location to only local machine.
  2. Once copy over, right click the backup file->Properties->Security tab
  3. Click Add, you should able to find a user name start with "SQLServerMSSQLUser$username$SQLEXPRESS", add this user and give your SQL user right to read and write.
  4. Open your database in SQL Server Management Studio
  5. In the Database folder, right click->Restore Database...  
       SQL Management Screenshoot2.1
  6. In the "To database:" field, type a new database name
  7. Select "From device:" option
  8. Click the browse button on the right and add your back up file.
  9. Click Option Tab
  10. Make sure your "Restore As" directory has "SQLServerMSSQLUser$username$SQLEXPRESS" security right.
       SQL Management Screenshoot3.1
  11. Double check your options, and select OK

In summary, the reason why you get an access denied error is because MS SQL Server Management Studio has its own user account when interacting with your system. As long as your SQLServerMSSQLUser$username$SQLEXPRESS has access to the read and write permission, you shouldn't encounter Access is denied error.

[Update Mar 3, 2009]

Thank you to an anonymous post, he/she reminded me that you may encounter access denied error if you pick an incorrect restore path.

MS SQL creates two files during restore, the .mdf and .ldf. Usually by default these files are restored to:
C:\Program Files\Microsoft SQL Server\MSSQL.1\MSSQL\Data\

However, sometime (for the reason I don’t know), the default restore path is not the same as above. You may not able to restore if the path doesn’t exist, but more importantly, it may not has the security right.

If you want to restore the database file to another directory, once again, make sure the restoring directory does not have any existing files and has "SQLServerMSSQLUser$username$SQLEXPRESS" user right. Otherwise SQL Management will not be able to write the files in your specified directory.