Posts RSS Comments RSS 137 Posts and 271 Comments till now

How To Determine The Size of .NET DataSet Object in Bytes

Apparently there is no way I haven’t find a way to determine the size of a .NET managed object in memory. The closest I can come out, particularly for a DataSet object is as follows:

DataSet ds = new DataSet();
// ...
// This is where you populate the content of DataSet
// ...
String xmlContent = ds.GetXml();
UnicodeEncoding uniEnc = new UnicodeEncoding();
int byteCount = uniEnc.GetByteCount(xmlContent);

But why we use UnicodeEncoding, not ASCIIEncoding, or UTF8Encoding, well, as MSDN says, String object is a collection of Unicode characters. So if we want to know how many bytes are they, we need to use UnicodeEncoding.

Of course we are still far from our actual objective, but this is a good start. I’ll update as I found other possible method.

 

How To Display HTML Without Saving To File First

The following code will work with the following requirements:

  1. You are using .NET Framework 2.0
  2. You already have WebBrowser control added into your Windows Form
public void DisplayHTML(String strHTML)
{
    if (strHTML != "")
    {
         if (this.webBrowser2.Document != null)
         {
               HtmlDocument doc = this.webBrowser2.Document.OpenNew(true);
               doc.Write(strHTML);
         }
         else
         {
               this.webBrowser2.DocumentText = strHTML;
         }
     }
}

Sorting Words by Their Length

Don’t ask why I come up with this post :) Let’s just say it has something to do with Regular Expression.

 

The first method that immediately come up to mind (and usually the worst :) ) is as follows:

struct Res
{
   //To Record the Result
   public String words;
   public int wordcount;
}

public static Res WorstWordByLengthSort(string raw)
{
   Res myresult = new Res();
   myresult.wordcount = 0;
   string[] words = raw.Split("n".ToCharArray());
   raw = "";
   foreach (string word in words)
      raw += word + " ";

   words = raw.Split(" ".ToCharArray());
   ArrayList ar = new ArrayList();

   foreach (string word in words)
   {
      string tstr = word.Trim();
      if (tstr == "")
         continue;
      myresult.wordcount++;
      if (ar.Count == 0)
      {
         ar.Add(tstr);
      }
      else
      {
          int count = ar.Count;
          bool inserted = false;
          for (int i = 0; i < count; i++)
          {
              if (ar[i].ToString().Length <= tstr.Length)
              {
                  if (!ar.Contains(tstr))
                  {
                      ar.Insert(i, tstr);
                      inserted = true;
                   }
              }
          }
          if (!inserted && !ar.Contains(tstr))
             ar.Add(tstr);
      }
   }
   StringBuilder sb = new StringBuilder();
   foreach (object o in ar)
       sb.AppendLine(o.ToString());
    myresult.words= sb.ToString();
    return myresult;
}

 

It will work flawlessly (sort of .. :) ), but it will not allow duplication of word. After tinkering for a while, I came up with an idea to improve its performance. A better solution would be to use a dictionary where the length of the word becomes the key. If a key is already exist in the dictionary, we just simply append the word into the value of that particular key. The idea is implemented as follows:

struct Res
{
   //To Record the Result
   public String words;
   public int wordcount;
}

public static Res BetterWordByLengthSort(string raw)
{
   Res myresult = new Res();
   myresult.wordcount = 0;
   myresult.words = "";
   StringBuilder result = new StringBuilder();
   Dictionary myDict = new Dictionary();
   ArrayList keys = new ArrayList();
   string[] words = raw.Split(”n”.ToCharArray());

   raw = “”;
   foreach (string word in words)
   {
      string tword = word.Trim();
      raw += tword + ” “;
   }
   words = null;
   words = raw.Split(” “.ToCharArray());

   foreach (string word in words)
   {
      string tempWord = word.Trim();
      if (tempWord == “”)
         continue;
      int tlength = tempWord.Length;
      if (myDict.ContainsKey(tlength))
      {
         myDict[tlength] = myDict[tlength] + “n” + tempWord;
      }
      else
      {
          keys.Add(tlength);
          myDict.Add(tlength, tempWord);
      }
      myresult.wordcount++;
   }
   //Sort the keys ASC
   keys.Sort();
   for (int i=keys.Count-1; i>=0; i–)
   {
      result.AppendLine(myDict[(int)keys[i]]);
   }
   myresult.words = result.ToString();
   return myresult;
}

I created a GUI project to compare their performance. With same input of 1443 words, the Worst method took 734 ms, while the Better method took only 15 ms. And yes, if you remember your Big O complexity, the Better method is definitely much more efficient compared to the Worst method :)

 

Traversing Database Server using SQL SMO

SQL SMO (SQL Management Object) is a collection of assemblies that shipped together with SQL 2005. This collection of assemblies is all that you need to control your SQL Server. Be it SQL 2005, or SQL 2000, you can control/manipulate it programmatically using SQL SMO.

 

Since SQL SMO gave you the ability to treat the database elements such as Table, Database, Stored Procedure, and Trigger as an object, interacting with them should be relatively easy and practical. Additionally, you might want to check out this list of things that make SQL SMO exciting.

 

OK, lets get our hand dirty with the project. The first step would be importing the references into your project. If you use Visual Studio 2005, look for Microsoft.SqlServer.Smo in the list of .NET assembly when you open ‘Add References’ window.
If you already have MS SQL 2005 installed, you can find the DLLs in the SDK\Assemblies folder of your MS SQL 2005 installation folder.
If you don’t have MS SQL 2005 installed in your computer, you might want to download the Express edition HERE.

 

Next, you could use the following code as reference.

using Microsoft.SqlServer.Management.Common;
using Microsoft.SqlServer.Management.Smo;
using System;
using System.Configuration;
using System.Data.SqlClient;

namespace Test
{
    class Program
    {
        static void Main(string[] args)
        {
            //Assuming that you include a Configuration file to your
            //project and set the key 'DataSource'
            //as the connection string
            SqlConnection conn = new SqlConnection(
                      ConfigurationManager.AppSettings["DataSource"]
            );
           //Instantiate the connection to the server
	   ServerConnection dbConn = new ServerConnection(conn);
	   //Instantiate the Database Server Object
	  Server dbServer = new Server(dbConn);			

          //Traverse the Database Objects
          foreach (Database db in dbServer.Databases)
          {
              if (db.IsAccessible)
              {
                  //traverse the Stored Procedure Objects
                  foreach (StoredProcedure sp in db.StoredProcedures)
                  {
                      foreach (string str in sp.Script())
                          Console.WriteLine(str);
                  }
                  //Traverse the Table Objects
                  foreach (Table tb in db.Tables)
                  {
                      foreach (string str in tb.Script())
                          Console.WriteLine(str);
                  }
                  //Traverse the View Objects
                  foreach (View vw in db.Views)
                  {
                      foreach (string str in vw.Script())
                          Console.WriteLine(str);
                  }
              }
          }
      }
  }
}

 

Make sure in your app.config you have the DataSource key. You can follow this template for the configuration file:



  
    
  

 

Have fun!

GUI Threading: A Beginner’s Help

GUI Programming used to be one of my nightmare in programming. I had a hard time understanding the concept and implemented it in my Windows Application. The good news is, I now know a little bit about it (^_^)/. Now by writing it into a blog post, I actually helping myself to understand the concept better, and hopefully, it might help others in one way or another. :-)

In this project, we will create a stopwatch (might be useful to track-down how long you need to create a blog post (^_^)/ ). OK, now please open your Visual Studio, and create a Windows Application. Name the project ‘ThreadingGUI_02′. After that, design the form to look something like this:
threading_02_form.png

So the idea is to create a process that will have a counter, increase the counter value and update the GUI every 0.1 seconds. In order to keep the GUI responsive to user’s actions, the actual processing should be done in different Thread. We also need to create a delegate, this way the the worker thread will be able to access the GUI thread and updates the corresponding labels.

Form1.cs

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Threading;

namespace ThreadingGUI_02
{
   public delegate void RefreshGUI(int i);

   public partial class Form1 : Form
   {
      Worker w;
      RefreshGUI myUpdateCounter;
      Thread t;
      public void UpdateCounter(int c)
      {
         if (this.InvokeRequired)
         {
            this.Invoke(myUpdateCounter, c);
         }
         else
         {
            int ms = c % 10;
            int second = (c / 10) % 60;
            int minute = (c / 600) % 60;
            int hour = (c / 36000) % 24;
            this.lblHour.Text = hour.ToString("00");
            this.lblMinute.Text = minute.ToString("00");
            this.lblSecond.Text = second.ToString("00");
            this.lblMiliSecond.Text = ms.ToString("0");
         }
      }
      public Form1()
      {
         InitializeComponent();
         myUpdateCounter = new RefreshGUI(UpdateCounter);
         w = new Worker(myUpdateCounter);
         t = new Thread(new ThreadStart(w.Counting));
         t.Start();
      }

      private void button1_Click(object sender, EventArgs e)
      {
         Button b = (Button)sender;
         b.Text = b.Text == "Start" ? "Stop" : "Start";
         w.isCounting = b.Text == "Stop";
         this.button2.Enabled = b.Text == "Start";
      }

      private void button2_Click(object sender, EventArgs e)
      {
         w.count = 0;
         int c = 0;
         int ms = c % 10;
         int second = (c / 10) % 60;
         int minute = (c / 600) % 60;
         int hour = (c / 36000) % 24;
         this.lblHour.Text = hour.ToString("00");
         this.lblMinute.Text = minute.ToString("00");
         this.lblSecond.Text = second.ToString("00");
         this.lblMiliSecond.Text = ms.ToString("0");
      }

      private void Form1_FormClosed(
         object sender,
         FormClosedEventArgs e)
      {
         t.Abort();
         t = null;
      }

      private void label5_Click(
         object sender,
         EventArgs e)
      {

      }
   }
}

 

Add a new class, and name it Worker.cs:

using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;

namespace ThreadingGUI_02
{
   class Worker
   {
      RefreshGUI update;
      public bool isCounting;
      public int count = 0;
      public Worker(RefreshGUI d)
      {
         update = d;
         isCounting = false;
      }
      public void Counting()
      {
         while (true)
         {
            if (isCounting)
            {
               ++count;
               if (update != null)
                  update(count);
            }
            Thread.Sleep(100);
         }

      }
   }
}

So as you see in the codes above, the logic of program would be:

  1. the main thread (a.k.a the GUI thread) instantiates the delegate
  2. GUI thread instantiates the worker thread, and pass the delegate object to worker thread object
  3. GUI thread starts the worker thread object
  4. the worker thread updates the GUI thread object using delegate
  5. the worker thread sleeps for a 0.1 seconds (If you do not need the 0.1 seconds delay, you could comment the Thread.Sleep(100); line)

 

This is example is not really a good example in threading since we never protect the ‘Critical Section‘ of the program with Mutex/Semaphore. Maybe in the future we will discuss how to prevent deadlock using Mutex/Semaphore.

For those who are lazy to copy and paste (^_^) into their Visual Studio, you can download the project solution: Threading GUI - Stopwatch

Close
E-mail It
Socialized through Gregarious 42