tag:blogger.com,1999:blog-69470376579929162562024-03-05T01:31:37.893-05:00Hantou Software DevelopmentHantouhttp://www.blogger.com/profile/16364616567528044982noreply@blogger.comBlogger15125tag:blogger.com,1999:blog-6947037657992916256.post-16808609048775403182010-02-05T10:35:00.000-05:002010-02-05T10:35:29.753-05:00C# Convert time to seconds since Jan 1, 2000<b>Scenario </b><br />
We know that the build-in DateTime object provide us a very convenience way to manipulate the number of seconds of time. However, for hardware device, there might be a limit with the buffer during the transmission. The DateTime starts counting the time since Jan 1, 0000. We will have 63082281600000000000 nanoseconds until Jan 1, 2000. For most of cases, we are not interested in any data between year 0000 and year 2000. Therefore, the following methods just give an alternative way to calculate and convert the number of seconds from DateTime object.<br />
<br />
<b>Method </b><br />
<div style="color: #6aa84f;"><b> </b>// Since 12:00:00 am Jan 1, 2000</div><b> </b><span style="color: blue;">public const long </span>INITIAL_DATETIME = 630822816000000000;<b> </b><br />
<br />
<span style="color: #6aa84f;">// Convert current time to number of seconds since Jan 1, 2000.</span><br />
<span style="color: blue;">public static int</span> GetTimeForDevice()<br />
{<br />
<span style="color: blue;">int </span>ans = 0;<br />
<br />
ans = (<span style="color: blue;">int</span>)((<span style="color: #3d85c6;">DateTime</span>.Now.Ticks - INITIAL_DATETIME) / 10000000);<br />
<br />
<span style="color: blue;">return </span>ans;<br />
}<br />
<br />
<span style="color: #6aa84f;">// Convert time from number of seconds since Jan 1, 2000 to a readable string</span><br />
<span style="color: blue;">public static string</span> GetTimeFromDevice(<span style="color: blue;">string </span>time)<br />
{<br />
<span style="color: blue;">string </span>ans = <span style="color: #a64d79;">""</span>;<br />
<br />
<span style="color: blue;">long </span>temp = <span style="color: #3d85c6;">Int32</span>.Parse(time) * 10000000 + INITIAL_DATETIME;<br />
<span style="color: #3d85c6;">DateTime </span>dt = new <span style="color: #3d85c6;">DateTime</span>(temp);<br />
ans = dt.ToShortDateString() + <span style="color: #a64d79;">" "</span> + dt.ToLongTimeString();<br />
<br />
<span style="color: blue;">return </span>ans;<br />
}Hantouhttp://www.blogger.com/profile/16364616567528044982noreply@blogger.com0tag:blogger.com,1999:blog-6947037657992916256.post-44147955471268075872009-06-19T14:47:00.008-04:002009-06-19T16:06:47.435-04:00C# How to convert byte arry to string<span style="font-weight: bold;">Scenario</span><br />How to a byte array to a string? The solution is using the 'GetString()' method from the ASCIIEncoding.ASCII object. Be carrefull with this method, it may cause problems if you try to convert something other than English, such as Chinese and other asian languages. In this case, you have to use specific ASCII encoding for that language.<br />For example, you probably want to use System.Text.Encoding.GetEncoding(1251).GetString(b);<br />Here, '1251' stands for English. You can choose your own codepage for Encoding or Decoding.<br /><br /><span style="font-weight: bold;">Method</span><br /><span style="color: rgb(0, 153, 0);"><span style="color: rgb(255, 0, 0);"><span style="color: rgb(0, 153, 0);"><span style="color: rgb(255, 0, 0);">byte[] data = ... ;</span> //whatever it is here<br /><span style="color: rgb(255, 0, 0);">string text1 = System.Text.ASCIIEncoding.ASCII.GetString(data);</span>//Let the ASCIIEncoding handle the convertion<br /></span></span></span><span style="color: rgb(0, 153, 0);"><span style="color: rgb(255, 0, 0);"><span style="color: rgb(0, 153, 0);"><span style="color: rgb(255, 0, 0);">string text2 = System.Text.Encoding.GetEncoding(1251).GetString(data);</span>// 1251 stands for English</span></span></span><br /><span style="color: rgb(0, 153, 0);"><span style="color: rgb(255, 0, 0);"><span style="color: rgb(0, 153, 0);"><span style="color: rgb(255, 0, 0);">string text3 = System.Text.Encoding.GetEncoding(28591).GetString(data);</span>// 28591 stands for Latin<br /></span></span></span><span style="color: rgb(0, 153, 0);"><span style="color: rgb(255, 0, 0);"><span style="color: rgb(0, 153, 0);"><span style="color: rgb(255, 0, 0);">string text4 = System.Text.Encoding.GetEncoding("GB18030").GetString(data);</span>// "GB18030" stands for Simplified Chinese</span></span></span>Hantouhttp://www.blogger.com/profile/16364616567528044982noreply@blogger.com0tag:blogger.com,1999:blog-6947037657992916256.post-74226537353322723872009-06-11T19:45:00.006-04:002009-06-11T19:59:00.640-04:00C# How to beep from your computer<span style="font-weight: bold;">Scenario</span><br />How to make a beep sound from your computer?<br />Although you can use any sound library to work for you, there is a simple way to make just a beep sound. This becomes useful especially when you are running a program for a long time and you want to be notified when any certain condition reaches.<br />Thanks to Microsoft, we can achieve this in one line of code with the build-in methods.<br /><br /><span style="font-weight: bold;">Method</span><br /><span style="color: rgb(0, 153, 0);"><span style="color: rgb(255, 0, 0);">Console.Beep();<span style="color: rgb(0, 153, 0);">//No parameter</span><br />Console.Beep(250, 250);<span style="color: rgb(0, 153, 0);">//Parameter: int frequency, int duration</span></span><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(255, 0, 0);"></span></span></span></span>Hantouhttp://www.blogger.com/profile/16364616567528044982noreply@blogger.com0tag:blogger.com,1999:blog-6947037657992916256.post-1726609191838780462009-05-13T17:15:00.013-04:002009-05-13T17:43:10.500-04:00C# Convert string to an array of bytes<span style="font-weight: bold;">Scenario</span><br />How to convert a string or a string array into a double array?<br />The .NET does not provide any method for us to call directly(if you found it, please let me know :D). However this is easy to implement within just a couple lines of code.<br /><br /><span style="font-weight: bold;">Method</span><br /><span style="color: rgb(0, 153, 0);"> //Convert 1 string to an array of bytes<br /> <span style="color: rgb(255, 0, 0);"> public static byte[] ConvertToBytes(string str)<br /> {<br /> byte[] ans = new byte[str.Length];<br /><br /> for (int i = 0; i < ans.Length; i++)<br /> {<br /> ans[i] = Convert.ToByte(str[i]);<br /> }<br /> <br /> return ans;<br /> }</span><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(255, 0, 0);"></span></span><br /></span></span>Hantouhttp://www.blogger.com/profile/16364616567528044982noreply@blogger.com0tag:blogger.com,1999:blog-6947037657992916256.post-28327215553059234512009-05-05T22:15:00.031-04:002009-05-11T21:10:50.448-04:00How to disable a TabPage in the TabControl<p><span style="font-weight: bold;">Scenario</span><br />The component <span class="blsp-spelling-error" id="SPELLING_ERROR_0">TabControl</span> in the Visual Studio <span class="blsp-spelling-error" id="SPELLING_ERROR_1">IDE</span> does not allow people to<br /> disable a certain <span class="blsp-spelling-error" id="SPELLING_ERROR_2">TabPage</span> within the <span class="blsp-spelling-error" id="SPELLING_ERROR_3">TabControl</span>. I have Googled for a long time<br /> and there is not any real solution regarding this issue. However, some people put a<br /> customized <span class="blsp-spelling-error" id="SPELLING_ERROR_4">TabControl</span> which allows you to disable the <span class="blsp-spelling-error" id="SPELLING_ERROR_5">TabPage</span>. I believe not<br /> everyone wants to download and try the third party software or plug-in.<br /><br /> <span style="font-weight: bold;">Method</span><br />I'm going to talk about a 'solution' which is more like a trick to solve this problem.<br /> For example, let's create a <span class="blsp-spelling-error" id="SPELLING_ERROR_6">TabControl</span> and it has 2 <span class="blsp-spelling-error" id="SPELLING_ERROR_7">TabPages</span>. Now before<br /> dragging any other objects from the tool list, drag a Panel object and drop into<br /> each one of those <span class="blsp-spelling-error" id="SPELLING_ERROR_8">TabPages</span>. Set those three Panels' Dock property to Fill so<br /> that the panel will be maximized within its <span class="blsp-spelling-error" id="SPELLING_ERROR_9">TabPage</span>. Now you will probably guess<br /> what I'm trying to tell you. Yes, you put all other objects on top of the panel.<br /> Then you just disable the panel if you want to disable a <span class="blsp-spelling-error" id="SPELLING_ERROR_10">TabPage</span>. Because the<br /> Panel is the Parent of the other components, the panel and its children will be<br /> disabled if we try to disable the panel itself.<br /><br /> <span style="font-weight: bold;">Details</span><br />Let's have a look at how this works.<br /><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiu2o523yyuWIj54zk-gjQ7sP_d25OlQfUqKuRmE3_9FdFUNxTd2bjdMD5PaMTmvabiZyUETtmmMYLzpSkNEzRmytHJh41Qg0F7ruwn_ycHot0JMo5DxT2B5MAxr8H6fg-pBJLFxx9ZizA/s1600-h/TabControl-Panel.png" onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}"><img id="BLOGGER_PHOTO_ID_5333079587443866802" alt="" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiu2o523yyuWIj54zk-gjQ7sP_d25OlQfUqKuRmE3_9FdFUNxTd2bjdMD5PaMTmvabiZyUETtmmMYLzpSkNEzRmytHJh41Qg0F7ruwn_ycHot0JMo5DxT2B5MAxr8H6fg-pBJLFxx9ZizA/s400/TabControl-Panel.png" style="cursor: pointer; width: 304px; height: 304px;" border="0" /></a><br />First, create a <span class="blsp-spelling-error" id="SPELLING_ERROR_11">TabControl</span> and drop a Panel onto one of the tab pages.</p><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiabudajiiENozmitiwcI7bh-fArt6oenpdE4CVJpnOyiNn3bZ5Zd2MFmDY2UxSlWRD0guORp4Gb1H5C3CA08ClKgPXr48XwJmHkYdMYKphZdW6-V7Sht6bw-GKgavqC2x348171suLjAs/s1600-h/Panel-Dock-Fill.png" onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}"><img id="BLOGGER_PHOTO_ID_5333079709940124594" alt="" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiabudajiiENozmitiwcI7bh-fArt6oenpdE4CVJpnOyiNn3bZ5Zd2MFmDY2UxSlWRD0guORp4Gb1H5C3CA08ClKgPXr48XwJmHkYdMYKphZdW6-V7Sht6bw-GKgavqC2x348171suLjAs/s400/Panel-Dock-Fill.png" style="cursor: pointer; width: 267px; height: 301px;" border="0" /></a><br /><p>Now, set the Dock to Fill for the panel</p><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj9meRvYQWFB-iZ43Kj5FPXdhO67xNGQurYUP7fja8Mu1qHX9jsLNVRLh3IBotHUuZM7EdM_PFxHZHKlYCAcTWHkv9f_h_uSd_pLcZx8iu7cdqr-gSYoGIky8zbIYDFck4PZQUBmyB6LKg/s1600-h/CheckBox-EnablePanel.png" onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}"><img id="BLOGGER_PHOTO_ID_5333079982475796546" alt="" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj9meRvYQWFB-iZ43Kj5FPXdhO67xNGQurYUP7fja8Mu1qHX9jsLNVRLh3IBotHUuZM7EdM_PFxHZHKlYCAcTWHkv9f_h_uSd_pLcZx8iu7cdqr-gSYoGIky8zbIYDFck4PZQUBmyB6LKg/s400/CheckBox-EnablePanel.png" style="cursor: pointer; width: 313px; height: 310px;" border="0" /></a><br /><p>Add some components to the <span class="blsp-spelling-error" id="SPELLING_ERROR_12">tabPage</span>1. Actually they are on top of the<br /> panel1. Run the sample application without checking the 'Enable Panel1'<br /> <span class="blsp-spelling-error" id="SPELLING_ERROR_13">checkbox</span>.</p><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjZ9g9qdYPw4teVP48VEVzxZw0MnI_NEY0BxdhD_AbhPYcnn2GIcPHKr3KZu5kdVsIVCYcCK5JxgU10DIOGbnm_aHYEdali5XaxHKCczD44iuDQ_59G81djFDvjw_8uUReR-krPbLp1DH4/s1600-h/CheckBox-CheckedChanged.png" onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}"><img id="BLOGGER_PHOTO_ID_5333080042623028242" alt="" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjZ9g9qdYPw4teVP48VEVzxZw0MnI_NEY0BxdhD_AbhPYcnn2GIcPHKr3KZu5kdVsIVCYcCK5JxgU10DIOGbnm_aHYEdali5XaxHKCczD44iuDQ_59G81djFDvjw_8uUReR-krPbLp1DH4/s400/CheckBox-CheckedChanged.png" style="cursor: pointer; width: 400px; height: 53px;" border="0" /></a><br /><p>The code implementation for the <span class="blsp-spelling-error" id="SPELLING_ERROR_14">checkbox</span>. Just for testing.<br /></p><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjPRoDCuXRPogVb2rf4vzHtQ67w8Si-amYk0cjlirt1ttlM3uLo3w3vIzugQXyoDcib0ixekLS912IQy_kANBXJ0cARv6I4VQJcyp1RKBDjmk-6GsttX3xLlghUOomrRvW1zJZ7IRTTiHY/s1600-h/CheckBox-DisablePanel.png" onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}"><img id="BLOGGER_PHOTO_ID_5333080128913595826" alt="" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjPRoDCuXRPogVb2rf4vzHtQ67w8Si-amYk0cjlirt1ttlM3uLo3w3vIzugQXyoDcib0ixekLS912IQy_kANBXJ0cARv6I4VQJcyp1RKBDjmk-6GsttX3xLlghUOomrRvW1zJZ7IRTTiHY/s400/CheckBox-DisablePanel.png" style="cursor: pointer; width: 313px; height: 310px;" border="0" /></a><br /><p>The effect shows the <span class="blsp-spelling-error" id="SPELLING_ERROR_15">tabPage</span>1 is 'disabled' once the <span class="blsp-spelling-error" id="SPELLING_ERROR_16">checkbox</span> is unchecked.<br /><br /> <span style="font-weight: bold;">Summary</span><br />This solution might not be perfect to everyone, but I believe it will help some<br /> people like me to solve a problem by using a simple solution. Remember the KISS<br /> principle? This is all about it!<br /> </p>Hantouhttp://www.blogger.com/profile/16364616567528044982noreply@blogger.com0tag:blogger.com,1999:blog-6947037657992916256.post-3529979521872064602009-05-03T22:02:00.009-04:002009-05-03T22:13:32.013-04:00Windows 7's Hardware Requirement<div style="text-align: center;"><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgD_7UlngKhqM7UIPgRXeGknh2LHIL7nw1pyu1trUT_aUiszkCV6JgWDAg2MNzEceFq2dBcdJ1Wyx2YTBmVSMik72n62R4OOmdxzpErbTEVgIUYQUBJfnHKB_00EXupx-7g7RY8-rx4g5g/s1600-h/HardwareRequiremtsForWindows.jpg"><img style="cursor: pointer; width: 565px; height: 151px;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgD_7UlngKhqM7UIPgRXeGknh2LHIL7nw1pyu1trUT_aUiszkCV6JgWDAg2MNzEceFq2dBcdJ1Wyx2YTBmVSMik72n62R4OOmdxzpErbTEVgIUYQUBJfnHKB_00EXupx-7g7RY8-rx4g5g/s400/HardwareRequiremtsForWindows.jpg" alt="" id="BLOGGER_PHOTO_ID_5331785874193457346" border="0" /></a><br /></div><div style="text-align: center;">The hardware requirements on different Windows Operating Systems<br /></div><br />The Windows 7 RC version has been released on Apr 30, 2009 for Technet subscribers only. On May 5 everyone should be able to get it for free. Here is the hardware requirement for installing Windows 7 RC on your computer. We can see that it is about the same as Windows Vista, but Windows 7 is 3 years later than Windows Vista.<br /><br /><p> Windows 7 Hardware Requirements:</p><p style="color: rgb(51, 102, 255);"> ·CPU 1GHz(32 bits OR 64 bits)。<span style="color: rgb(230, 230, 221);"><br /></span></p><p style="color: rgb(51, 102, 255);"> ·1GB Memory(32 Bits);2GB(64 Bits)。<span style="color: rgb(230, 230, 221);"><br /></span></p><p style="color: rgb(51, 102, 255);"> ·16GB Hard Drive(32 Bits);20GB Hard Drive(64 Bits)。</p><span style="color: rgb(51, 102, 255);"> ·Support WDDM 1.0 or higher DirectX 9</span>Hantouhttp://www.blogger.com/profile/16364616567528044982noreply@blogger.com0tag:blogger.com,1999:blog-6947037657992916256.post-3103957390055617322009-05-01T16:31:00.014-04:002009-05-03T17:14:27.306-04:00Convert File Size To Readable Format<b>Scenario</b><br />When we use "Windows + E" to browse files, we will see the file size of each file under the "Details" mode. Every file has a file size, but by default all file sizes are displayed in one unit 'KB'. This makes people difficult to make sense if the file size is greater than 10MB, because you will see a lot of numeric digits before the dot symbol.<br /><br /><b>Method</b><br />The following table is not magic and the issue mentioned above is not hard to solve. Here is a way to convert the file size into human readable format under normal circumstance.<br /><br /><span style="color: rgb(255, 0, 0);"><b>1 KB = 1024 Byte = 1024 Byte<br />1 MB = 1024 KB = 1024 * 1024 Byte = 1048576 Byte<br />1 GB = 1024 MB = 1024 * 1024 KB = 1024 * 1024 * 1024 Byte = 1073741824 Byte</b></span><br /><br />To convert the file size you retrieve from the original "File.Length" method, we can use the above table to check the byte count.<br /><br /><b>Code</b><br /><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjXp_ExJ5k-3YD1F0bFULNuwyK5EV2IptTRjO4UOb89sxlKu8CM7w_xS00ynysBSN21z3clUUJk4LMb-8266okjunFB_RDyCZC-SM8Wis7z9AmlSSeN6L4_ZP5e2D5O76Spj07tzMbpHE4/s1600-h/GetFileSize.png"><img style="cursor: pointer; width: 579px; height: 330px;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjXp_ExJ5k-3YD1F0bFULNuwyK5EV2IptTRjO4UOb89sxlKu8CM7w_xS00ynysBSN21z3clUUJk4LMb-8266okjunFB_RDyCZC-SM8Wis7z9AmlSSeN6L4_ZP5e2D5O76Spj07tzMbpHE4/s400/GetFileSize.png" alt="" id="BLOGGER_PHOTO_ID_5331424219323721346" border="0" /></a><br /><b>Conclusion</b><br />As you see, after calling the "GetFileSize" method, it will return a converted format of file size string. The implementation is only a few if statements.<br />You can copy & modify the above code for your convenience.Hantouhttp://www.blogger.com/profile/16364616567528044982noreply@blogger.com0tag:blogger.com,1999:blog-6947037657992916256.post-77364116396178766332009-04-28T12:23:00.022-04:002009-04-28T13:31:31.586-04:00C# Convert string to double array<span style="font-weight: bold;">Scenario</span><br />How to convert a string or a string array into a double array?<br />The .NET does not provide any method for us to call directly. However this is easy to implement within just a couple lines of code.<br /><br /><span style="font-weight: bold;">Method<br /></span><span style="color: rgb(255, 0, 0);">//str is the input string that contains a sequence of numbers<br />string[] arrString = str.Split(new char[] { ' ' });//you can define your own way to split the string</span><br /><span style="color: rgb(255, 0, 0);"> double[] arrDouble = new double[arrString.Length];</span><br /><span style="color: rgb(255, 0, 0);"> for (int i = 0; i < arrString.Length; i++)<br /><span style="color: rgb(255, 0, 0);">{ </span><br /><span style="color: rgb(255, 0, 0);">arrDouble[i] = double.Parse(arrString[i]); </span><br /><span style="color: rgb(255, 0, 0);">} </span></span>Hantouhttp://www.blogger.com/profile/16364616567528044982noreply@blogger.com0tag:blogger.com,1999:blog-6947037657992916256.post-90883300749706779852009-04-28T10:39:00.030-04:002009-04-28T12:23:35.306-04:00C# Cross-Thread Operations<h2><span style="font-size:100%;"><span style="font-weight: bold;">Cross-Thread Operations</span></span></h2> <p class="style16 style21">Many of you may have seen the cross-thread exception when dealing with Cross-Thread operations. For example, if you try to call a <span class="style35">Form</span> function from a separate thread, you will get an error message similar to:</p> <p style="font-style: italic; color: rgb(51, 51, 255);" class="style35">Cross-thread operation not valid: Control 'Form1' accessed from a thread other than the thread it was created on.<span><span></span></span></p><p style="color: rgb(0, 0, 0);" class="style35">That is, you cannot manA <span style="font-weight: bold;">Cross-Thread operation</span> in C# is a call that accesses components from a different thread. Handling corss-thread is a requirement starting with .NET Framework 2.0. We are going to discuss how to make cross-thread calls between controls.</p> <h2 class="style16 style27"><span style="font-size:100%;"><strong>Delegates</strong></span></h2> <p class="style16 style21">The answer is simply to use delegates to invoke methods that use cross-thread operations. Using delegates is an elegant way to call methods that are from other threads.</p> <h2 class="style16 style27"><span style="font-size:100%;"><strong>Methods</strong></span></h2> <p class="style16 style21">The example is quite simple. Let's create a blank winForm application. Then create a second thread called <span style="font-style: italic;">secondThread</span>. Within the <span style="font-style: italic;">secondThread</span>, we try to change the text of 'Form1'. The above exception message will pop up if the following stuff is not implemented.<br /></p> <h2 class="style16 style27"><span style="font-size:100%;"><strong>InvokeRequired</strong></span></h2> <p class="style16 style21">The key for cross-thread calls is in the InvokeRequired property. When cross-threading will be required, the property will be true. This is a way to let you know wether you are in a cross-thread issue or not. You can then use delegates to invoke the method properly:</p> <pre style="color: rgb(255, 0, 0);"><span class="style36">if</span> (<span class="style36">this</span>.InvokeRequired)<br />{<br />DoSth<span class="style37">Delegate</span> aDelegate = new DoSth<span class="style37">Delegate</span>(DoSth); <span class="style38">//delegate</span><br /><span class="style36"> this</span>.Invoke(aDelegate); <span class="style38">//call</span> the method<br />}<br /><span class="style36">else</span><br />{<br /><span class="style38"> //Your code here</span><br />}</pre> <p style="font-weight: bold;" class="style16 style21">Others</p><p class="style16 style21">For more about delegates, refer to <a href="http://msdn.microsoft.com/en-us/library/ms173171%28VS.80%29.aspx" target="_blank">http://msdn.microsoft.com/en-us/library/ms173171(VS.80).aspx<br /></a>For more about Invoke method, refer to <a href="http://msdn.microsoft.com/en-us/library/zyzhdc6b.aspx" target="_blank">http://msdn.microsoft.com/en-us/library/zyzhdc6b.aspx</a><br /></p>Hantouhttp://www.blogger.com/profile/16364616567528044982noreply@blogger.com0tag:blogger.com,1999:blog-6947037657992916256.post-64523177178801753822009-04-21T10:41:00.030-04:002009-04-24T10:56:14.678-04:00MCTS for C# Developers<a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgCT2q7quL7Om9RJDjwWs3Cw0-kWBNMqzu5DCQWMMBwSyk6-FZEhO5XUBxU1Uc7CiZm0FyhpCpj8tbKJdCac2pkeFoXwgEEBCK3dQod1KtYpFIGGmz2EqhQc1veIRPQo63HvzloxMWXJRQ/s1600-h/mcts.png"><img style="margin: 0pt 10pt 10px 10px; float: left; cursor: pointer; width: 130px; height: 93px;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgCT2q7quL7Om9RJDjwWs3Cw0-kWBNMqzu5DCQWMMBwSyk6-FZEhO5XUBxU1Uc7CiZm0FyhpCpj8tbKJdCac2pkeFoXwgEEBCK3dQod1KtYpFIGGmz2EqhQc1veIRPQo63HvzloxMWXJRQ/s400/mcts.png" alt="" id="BLOGGER_PHOTO_ID_5327173001996394722" border="0" /></a><span style="font-weight: bold;">Microsoft Certified Technology Specialist (MCTS)</span><br />The Microsoft Certified Technology Specialist (<span style="font-weight: bold;">MCTS</span>) certifications enable professionals to target specific technologies and to distinguish themselves by demonstrating in-depth knowledge and expertise in their specialized technologies. An MCTS is consistently capable of implementing, building, troubleshooting, and debugging a particular Microsoft technology.<br /><br /><br /><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj970Vk1VmMYyhCfl2WaCSRq77aSylk8AoEuu2-dTnXPPSdqTUf5-Fwn1jun-iVpYBZiZNRH9hdq83fmZICOT3BWlxEwCmfSWWYIJZunWVOVNIY9ESiTxAXAErfd_PeBJIY1jXA6sDGmPc/s1600-h/new_ms_cert.gif"><img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 289px; height: 294px;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj970Vk1VmMYyhCfl2WaCSRq77aSylk8AoEuu2-dTnXPPSdqTUf5-Fwn1jun-iVpYBZiZNRH9hdq83fmZICOT3BWlxEwCmfSWWYIJZunWVOVNIY9ESiTxAXAErfd_PeBJIY1jXA6sDGmPc/s400/new_ms_cert.gif" alt="" id="BLOGGER_PHOTO_ID_5327173104874600450" border="0" /></a>The following three exams are the most common three people take before reaching the top of the above pyramid. After passing the each one of them, you will be able to create your own Microsoft Certification Logo. E.g.<br /><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEinpkm0a17QGPSK80UFQ1dby4pmBvccnquBJ7P_tYGekajIyulJPIo0Nr49eCdKX-PpfwaTVIJZJaeFQM01MkJtf5YY4X_OCF6xzIMLOzcuyefbK-fczFfjjofk4Q5Nv1YsVYzVJ5Vcnfo/s1600-h/MCTS(rgb)_512.png"><img style="cursor: pointer; width: 256px; height: 80px;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEinpkm0a17QGPSK80UFQ1dby4pmBvccnquBJ7P_tYGekajIyulJPIo0Nr49eCdKX-PpfwaTVIJZJaeFQM01MkJtf5YY4X_OCF6xzIMLOzcuyefbK-fczFfjjofk4Q5Nv1YsVYzVJ5Vcnfo/s400/MCTS(rgb)_512.png" alt="" id="BLOGGER_PHOTO_ID_5327176325537759090" border="0" /></a><br />You can go to the MCP website and order your own MCTS certification. It should be mailed to you within 1 ~ 2 months. Here is a sample certification you will get. Obviously, "YOUR NAME" means your real name will be placed there.<br /><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg053qmX3Z4WonrhJRGFfunmkxQ4_jMhgWF4Q-afnE_lXqPVKpoCaD9XUnQeDf0pyQJ-q9c6qdpOXt5q5ydvlCc7ZFaK7kptAnhVm80Kvfm7LwuGsj_M1BXerGEmL8AAaOXE00ZIhUB0_I/s1600-h/MCTS.Windows.jpg"><img style="cursor: pointer; width: 400px; height: 300px;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg053qmX3Z4WonrhJRGFfunmkxQ4_jMhgWF4Q-afnE_lXqPVKpoCaD9XUnQeDf0pyQJ-q9c6qdpOXt5q5ydvlCc7ZFaK7kptAnhVm80Kvfm7LwuGsj_M1BXerGEmL8AAaOXE00ZIhUB0_I/s400/MCTS.Windows.jpg" alt="" id="BLOGGER_PHOTO_ID_5328271511438548994" border="0" /></a><br /><br /><br /><span style="font-weight: bold;">Exam 70-536</span><br />Microsoft .NET Framework - Application Development Foundation <a style="font-style: italic;" href="http://www.microsoft.com/learning/en/us/exams/70-536.aspx" target="_blank">more<br /></a>Training Kit <a style="font-style: italic;" href="http://www.megaupload.com/?d=E4GHVB5G" target="_blank">download link</a><br /><br /><span style="font-weight: bold;">Exam 70-526</span><br />Microsoft .NET Framework 2.0 – Windows-Based Client Development <a style="font-style: italic;" href="http://www.microsoft.com/learning/en/us/exams/70-526.mspx" target="_blank">more</a><br />Training Kit <a style="font-style: italic;" href="http://www.megaupload.com/?d=GCQY4BJT" target="_blank">download link</a><br /><br /><span style="font-weight: bold;">Exam 70-528</span><br />Microsoft .NET Framework 2.0 - Web-Based Client Development <a style="font-style: italic;" href="http://www.microsoft.com/learning/en/us/exams/70-528.mspx" target="_blank">more</a><br />Training Kit <a style="font-style: italic;" href="http://www.megaupload.com/?d=KMFHIKMV" target="_blank">download link</a>Hantouhttp://www.blogger.com/profile/16364616567528044982noreply@blogger.com0tag:blogger.com,1999:blog-6947037657992916256.post-68099212393494465772009-04-16T10:11:00.051-04:002009-04-28T09:50:26.947-04:00Simple Messenger - A C# MSN Messenger-like Chat Application<a style="color: rgb(51, 51, 255);" href="http://www.megaupload.com/?d=PCX7V6QR" target="_blank">Download sample application here</a><br /><br /><img alt="SimpleMessenger.JPG" src="http://www.codeproject.com/KB/miscctrl/SimpleMessenger/SimpleMessenger.JPG" width="480" height="546" /> <p><img alt="SimpleMessenger_About.JPG" src="http://www.codeproject.com/KB/miscctrl/SimpleMessenger/SimpleMessenger_About.JPG" width="343" height="262" /> </p> <h2>Introduction</h2> <p>This is a simple MSN Messenger like chat application using socket programming. It allows the users to send and receive messages by running two Simple Messengers.<br />You can read this article from my blog: <a href="http://hantou.blogspot.com/">http://hantou.blogspot.com/</a>.</p> <p>There are two specific features other than the regular MSN Messenger:</p> <ol><li>'<code>Hex</code>'</li><ul><li>TRUE: The data will be displayed in Hex format.</li><li>FALSE: The data will be displayed in regular text. </li></ul><li>'<code>No print on receiving</code>'</li><ul><li>TRUE: The received data will not be printed on the textbox.</li><li>FALSE: The received data will be printed on the textbox. </li></ul></ol> <h2>Background</h2> <p>One day when I was working on socket programming, I needed to monitor data transmission. Although Visual Studio already has a debugger for the user to monitor the data, I still needed a third application to cache the data and take a look at it. This comes with the idea for the Simple Messenger. You can use this program as a chat application when you run two simple Messengers. If you connect your computer to a device, another software, a web application, etc., you will be able to send/receive data via one Simple Messenger application. In my case, I just connect my computer to a device which has Ethernet connection and I need to monitor the data sent by the device during the run time. The main purpose of this article here is to share this program with you regarding socket programming and multiple threads. </p> <h2>KeyValuePair </h2> <p>A helper class wraps a <code>Socket</code> and a <code><span class="code-SDKkeyword">byte</span></code> array.</p> <div class="SmallText" id="premain0" style="width: 100%; cursor: pointer;"><img preid="0" src="http://www.codeproject.com/images/minus.gif" id="preimg0" width="9" height="9" /><span preid="0" style="margin-bottom: 0pt;" id="precollapse0"> Collapse</span></div><pre style="margin-top: 0pt;" id="pre0" lang="cs"><span class="code-keyword">public</span> <span class="code-keyword">class</span> KeyValuePair<br />{<br /><span class="code-keyword">public</span> Socket socket;<br /><span class="code-keyword">public</span> <span class="code-keyword">byte</span>[] dataBuffer = <span class="code-keyword">new</span> <span class="code-keyword">byte</span>[<span class="code-digit">1</span>];<br />} </pre> <h2>Overview</h2> <p>There are two main classes named <em>Server.cs</em> and <em>Client.cs</em> standing for Server mode and Client mode respectively. Note, the scenario is that only one server and one client are connected. This means that if you try to open one server and multiple clients then I cannot promise anything. The one-to-many case is not implemented and this is beyond the main issue that is being discussed here.</p> <h2>Connection </h2> <p>The connection is slightly different between the Server Mode and the Client Mode. </p> <p>First look at the <strong>Server Mode</strong>: </p> <div class="SmallText" id="premain1" style="width: 100%; cursor: pointer;"><img preid="1" src="http://www.codeproject.com/images/minus.gif" id="preimg1" width="9" height="9" /><span preid="1" style="margin-bottom: 0pt;" id="precollapse1"> Collapse</span></div><pre style="margin-top: 0pt;" id="pre1" lang="cs"><span class="code-keyword">public</span> <span class="code-keyword">void</span> Connect(<span class="code-keyword">string</span> ipAddr, <span class="code-keyword">string</span> port)<br />{<br />server = <span class="code-keyword">new</span> Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);<br />IPEndPoint ipLocal = <span class="code-keyword">new</span> IPEndPoint(IPAddress.Any, Convert.ToInt32(port));<br />server.Bind(ipLocal);<span class="code-comment">//</span><span class="code-comment">bind to the local IP Address...</span><br />server.Listen(<span class="code-digit">5</span>);<span class="code-comment">//</span><span class="code-comment">start listening...</span><br /><br /><span class="code-comment">//</span><span class="code-comment"> create the call back for any client connections...</span><br />server.BeginAccept(<span class="code-keyword">new</span> AsyncCallback(OnClientConnect), <span class="code-keyword">null</span>);<br />}</pre> <p>The server needs to watch for the connection to see if there is any client trying to connect to it. </p> <div class="SmallText" id="premain2" style="width: 100%; cursor: pointer;"><img preid="2" src="http://www.codeproject.com/images/minus.gif" id="preimg2" width="9" height="9" /><span preid="2" style="margin-bottom: 0pt;" id="precollapse2"> Collapse</span></div><pre style="margin-top: 0pt;" id="pre2" lang="cs"><span class="code-keyword">public</span> <span class="code-keyword">void</span> OnClientConnect(IAsyncResult asyn)<br />{<br /><span class="code-keyword">try</span><br />{<br /><span class="code-keyword">if</span> (server != <span class="code-keyword">null</span>)<br />{<br /> tempSocket = server.EndAccept(asyn);<br /> WaitForData(tempSocket);<br /> server.BeginAccept(<span class="code-keyword">new</span> AsyncCallback(OnClientConnect), <span class="code-keyword">null</span>);<br />}<br />}<br /><span class="code-comment">/*</span><span class="code-comment"> ... */</span><br />} </pre> <p>Before the server socket receives any data, we must prepare for it ahead. Here the <code>KeyValuePair</code> object is imported as a parameter. </p> <div class="SmallText" id="premain3" style="width: 100%; cursor: pointer;"><img preid="3" src="http://www.codeproject.com/images/minus.gif" id="preimg3" width="9" height="9" /><span preid="3" style="margin-bottom: 0pt;" id="precollapse3"> Collapse</span></div><pre style="margin-top: 0pt;" id="pre3" lang="cs"><span class="code-keyword">public</span> <span class="code-keyword">void</span> WaitForData(Socket soc)<br />{<br /><span class="code-keyword">try</span><br />{<br /><span class="code-keyword">if</span> (asyncCallBack == <span class="code-keyword">null</span>)<br /> asyncCallBack = <span class="code-keyword">new</span> AsyncCallback(OnDataReceived);<br /><br />KeyValuePair aKeyValuePair = <span class="code-keyword">new</span> KeyValuePair();<br />aKeyValuePair.socket = soc;<br /><br /><span class="code-comment">//</span><span class="code-comment"> now start to listen for incoming data...</span><br />aKeyValuePair.dataBuffer = <span class="code-keyword">new</span> <span class="code-keyword">byte</span>[soc.ReceiveBufferSize];<br />soc.BeginReceive(aKeyValuePair.dataBuffer, <span class="code-digit">0</span>, aKeyValuePair.dataBuffer.Length,<br /> SocketFlags.None, asyncCallBack, aKeyValuePair);<br />}<br /><span class="code-comment">/*</span><span class="code-comment"> ... */</span><br />} </pre> <p>Now look at the <strong>Client Mode</strong>: </p> <div class="SmallText" id="premain4" style="width: 100%; cursor: pointer;"><img preid="4" src="http://www.codeproject.com/images/minus.gif" id="preimg4" width="9" height="9" /><span preid="4" style="margin-bottom: 0pt;" id="precollapse4"> Collapse</span></div><pre style="margin-top: 0pt;" id="pre4" lang="cs"><span class="code-keyword">public</span> <span class="code-keyword">void</span> Connect(<span class="code-keyword">string</span> ipAddr, <span class="code-keyword">string</span> port)<br />{<br />client = <span class="code-keyword">new</span> Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);<br />IPEndPoint ipe = <span class="code-keyword">new</span> IPEndPoint(IPAddress.Parse(ipAddr), Convert.ToInt32(port));<br />client.Connect(ipe);<br /><br />clientListener = <span class="code-keyword">new</span> Thread(OnDataReceived);<br />isEndClientListener = <span class="code-keyword">false</span>;<br />clientListener.Start();<br />}</pre> <img alt="ServerClient.JPG" src="http://www.codeproject.com/KB/miscctrl/SimpleMessenger/ServerClient.JPG" width="448" height="255" /> <h2>Data Receive</h2> <p>Since the <code>AsyncCallback</code> is used for the server, receiving the data will be different. </p> <h4>For the Server Mode </h4> <div class="SmallText" id="premain5" style="width: 100%; cursor: pointer;"><img preid="5" src="http://www.codeproject.com/images/minus.gif" id="preimg5" width="9" height="9" /><span preid="5" style="margin-bottom: 0pt;" id="precollapse5"> Collapse</span></div><pre style="margin-top: 0pt;" id="pre5" lang="cs">KeyValuePair aKeyValuePair = (KeyValuePair)asyn.AsyncState;<br /><span class="code-comment">//</span><span class="code-comment">end receive...</span><br /><span class="code-keyword">int</span> iRx = <span class="code-digit">0</span>;<br />iRx = aKeyValuePair.socket.EndReceive(asyn);<br /><span class="code-keyword">if</span> (iRx != <span class="code-digit">0</span>)<br />{<br /><span class="code-keyword">byte</span>[] recv = aKeyValuePair.dataBuffer;<br />}</pre> <h4>For the Client Mode</h4> <div class="SmallText" id="premain6" style="width: 100%; cursor: pointer;"><img preid="6" src="http://www.codeproject.com/images/minus.gif" id="preimg6" width="9" height="9" /><span preid="6" style="margin-bottom: 0pt;" id="precollapse6"> Collapse</span></div><pre style="margin-top: 0pt;" id="pre6" lang="cs"><span class="code-keyword">byte</span>[] recv = <span class="code-keyword">new</span> <span class="code-keyword">byte</span>[client.ReceiveBufferSize]; <span class="code-comment">//</span><span class="code-comment">you can define your own size</span><br /><span class="code-keyword">int</span> iRx = client.Receive(recv );<br /><span class="code-keyword">if</span> (iRx != <span class="code-digit">0</span>)<br />{<br /><span class="code-comment">//</span><span class="code-comment">recv should contain the received data.</span><br />}</pre> <h2>Data Send</h2> <p>Sending the data is as easy as calling the <code>Send()</code> method that comes with the <code>Socket</code>. E.g. </p> <div class="SmallText" id="premain7" style="width: 100%; cursor: pointer;"><img preid="7" src="http://www.codeproject.com/images/minus.gif" id="preimg7" width="9" height="9" /><span preid="7" style="margin-bottom: 0pt;" id="precollapse7"> Collapse</span></div><pre style="margin-top: 0pt;" id="pre7" lang="cs">soc.Send(dataBytes);<span class="code-comment">//</span><span class="code-comment">'soc' could either be the server or the client</span></pre> <h2>Error Handling</h2> <p>In Server's receive block, you might want to handle the <code>SocketException </code>with <code>ErrorCode == <span class="code-digit">10054</span></code>. This error code indicates the connection reset for peers. Refer to <a href="http://msdn.microsoft.com/en-us/library/ms740668%28VS.85%29.aspx">MSDN</a>.</p> <div class="SmallText" id="premain8" style="width: 100%; cursor: pointer;"><img preid="8" src="http://www.codeproject.com/images/minus.gif" id="preimg8" width="9" height="9" /><span preid="8" style="margin-bottom: 0pt;" id="precollapse8"> Collapse</span></div><pre style="margin-top: 0pt;" id="pre8" lang="cs"><span class="code-keyword">if</span> (e.ErrorCode == <span class="code-digit">10054</span>)<span class="code-comment">//</span><span class="code-comment">Connection reset, </span><br /><span class="code-comment">//</span><span class="code-comment"> <a>http://msdn.microsoft.com/en-us/library/ms740668(VS.85).aspx</a></span><br />{<br /><span class="code-comment">/*</span><span class="code-comment"> ... */</span><br />}</pre> <h2>Points of Interest</h2> <p>Every time I used the MSN Messenger to chat with my friends, I was worried if my conversation would be recorded by 'MSN'. Now I'm happy and 'safe' to use my own chat application to chat with my friends, er... within a local network. However, the main benefit of this program is that I learned how to play with the Ethernet and sockets. I hope this will benefit you as well.</p> <p>For more information about me, please visit my blog: <a href="http://hantou.blogspot.com/">hantou.blogspot.com</a>.</p> <h2>History</h2> <ul><li>2<sup>nd</sup> July, 2008 - First version </li><li>16<sup>th</sup> April, 2009 - Updated article downloads and images</li><li>20<sup>th</sup> April, 2009 - Updated article</li></ul> <!-- Main Page Contents End --> <form name="aspnetForm" method="post" action="displayarticle.aspx" id="aspnetForm" style="margin: 0pt; padding: 0pt;"> <div> <input name="__VIEWSTATE" id="__VIEWSTATE" value="/wEPDwUKMTAyMTMzODg1Ng9kFgJmD2QWBAILD2QWBgIDDw8WAh4HVmlzaWJsZWdkZAIJDw8WAh8AZ2RkAgwPDxYCHwBnZGQCDA9kFgoCBw9kFg4CAQ9kFgJmDxYCHgtfIUl0ZW1Db3VudGZkAgMPZBYKZg8PFgIeC05hdmlnYXRlVXJsBS8vS0IvbWlzY2N0cmwvU2ltcGxlTWVzc2VuZ2VyLmFzcHg/ZGlzcGxheT1QcmludGRkAgEPDxYCHwIFJi9zY3JpcHQvQXJ0aWNsZXMvUmVwb3J0LmFzcHg/YWlkPTI3NjgxZGQCAg9kFgQCBA8PFgIfAgU9L3NjcmlwdC9Cb29rbWFya3MvQWRkLmFzcHg/b2JpZD0yNzY4MSZvYnRpZD0yJmFjdGlvbj1BZGRXYXRjaBYGHgRuYW1lBQtibXdfMjc2ODFfMh4FY2xhc3NlHgdvbmNsaWNrBRlyZXR1cm4gd2F0Y2hNZSgyNzY4MSwgMik7ZAIGDxYCHwMFC2Jtd18yNzY4MV8yZAIDD2QWBAIEDw8WAh8CBUAvc2NyaXB0L0Jvb2ttYXJrcy9BZGQuYXNweD9vYmlkPTI3NjgxJm9idGlkPTImYWN0aW9uPUFkZEJvb2ttYXJrFgYfAwUKYm1fMjc2ODFfMh8EZR8FBRxyZXR1cm4gYm9va21hcmtNZSgyNzY4MSwgMik7ZAIGDxYCHwMFCmJtXzI3NjgxXzJkAgUPDxYCHwIFMS9zY3JpcHQvY29tbW9uL1RlbGxGcmllbmQuYXNweD9vYnRpZD0yJm9iaWQ9Mjc2ODFkZAIFD2QWBAIBD2QWAgIBDw8WAh4EVGV4dAUaMTIgdm90ZXMgZm9yIHRoaXMgYXJ0aWNsZS5kZAIHD2QWAmYPZBYEAgEPDxYEHwYFEFBvcHVsYXJpdHk6IDMuOTYfAgUpL3NjcmlwdC9BcnRpY2xlcy9Ub3BBcnRpY2xlcy5hc3B4P3RhX3NvPTFkZAIFDxYCHwYFHFJhdGluZzogPGI+My42NzwvYj4gb3V0IG9mIDVkAhkPZBYIAgEPZBYEAgEPFgIeCWlubmVyaHRtbAW2ATxwPlRoaXMgYXJ0aWNsZSwgYWxvbmcgd2l0aCBhbnkgYXNzb2NpYXRlZCBzb3VyY2UgY29kZSBhbmQgZmlsZXMsIGlzIGxpY2Vuc2VkIHVuZGVyIDxhIGhyZWY9Imh0dHA6Ly93d3cuY29kZXByb2plY3QuY29tL2luZm8vY3BvbDEwLmFzcHgiPlRoZSBDb2RlIFByb2plY3QgT3BlbiBMaWNlbnNlIChDUE9MKTwvYT48L3A+ZAICD2QWAgIBDxBkZBYAZAIFDxYCHwECAWQCBw8WAh8GBdAIPGgyPk90aGVyIHBvcHVsYXIgTWlzY2VsbGFuZW91cyBhcnRpY2xlczo8L2gyPjx1bD48bGk+PGEgaHJlZj0iL0tCL21pc2NjdHJsL2dyaWRjdHJsLmFzcHgiPk1GQyBHcmlkIGNvbnRyb2wgMi4yNjwvYT48ZGl2IGNsYXNzPSJTbWFsbFRleHQiPkEgZnVsbHkgZmVhdHVyZWQgTUZDIGdyaWQgY29udHJvbCBmb3IgZGlzcGxheWluZyB0YWJ1bGFyIGRhdGEuIFRoZSBncmlkIGlzIGEgY3VzdG9tIGNvbnRyb2wgZGVyaXZlZCBmcm9tIENXbmQ8L2Rpdj48L2xpPjxsaT48YSBocmVmPSIvS0IvbWlzY2N0cmwvWFBUYXNrQmFyLmFzcHgiPlRoZW1lZCBXaW5kb3dzIFhQIHN0eWxlIEV4cGxvcmVyIEJhcjwvYT48ZGl2IGNsYXNzPSJTbWFsbFRleHQiPkEgZnVsbHkgY3VzdG9taXphYmxlIFdpbmRvd3MgWFAgc3R5bGUgRXhwbG9yZXIgQmFyIHRoYXQgc3VwcG9ydHMgV2luZG93cyBYUCB0aGVtZXMgYW5kIGFuaW1hdGVkIGV4cGFuZC9jb2xsYXBzZSB3aXRoIHRyYW5zcGFyZW5jeS48L2Rpdj48L2xpPjxsaT48YSBocmVmPSIvS0IvbWlzY2N0cmwvdGFza2Jhcm5vdGlmaWVyLmFzcHgiPlRhc2tiYXJOb3RpZmllciwgYSBza2lubmFibGUgTVNOIE1lc3Nlbmdlci1saWtlIHBvcHVwIGluIEMjIGFuZCBub3cgaW4gVkIuTkVUIHRvbzwvYT48ZGl2IGNsYXNzPSJTbWFsbFRleHQiPlRoZSBUYXNrYmFyTm90aWZpZXIgY2xhc3MgYWxsb3dzIHRvIGRpc3BsYXkgYW4gTVNOIE1lc3Nlbmdlci1saWtlIGFuaW1hdGVkIHBvcHVwIHdpdGggYSBza2lubmVkIGJhY2tncm91bmQ8L2Rpdj48L2xpPjxsaT48YSBocmVmPSIvS0IvbWlzY2N0cmwvcHB0b29sdGlwLmFzcHgiPkNQUFRvb2xUaXAgdjIuMTwvYT48ZGl2IGNsYXNzPSJTbWFsbFRleHQiPkEgY2xhc3MgdGhhdCBhbGxvd3MgeW91IHRvIGRpc3BsYXkgeW91ciBkYXRhIGZvciBhIGNvbnRyb2wgYXMgdG9vbHRpcDwvZGl2PjwvbGk+PGxpPjxhIGhyZWY9Ii9LQi9taXNjY3RybC9mb3JtdWxhY3RybC5hc3B4Ij5Gb3JtdWxhIEVkaXRvcjwvYT48ZGl2IGNsYXNzPSJTbWFsbFRleHQiPkZvcm11bGEtZWRpdG9yIGZvciBlZGl0aW5nIGFuZCBleHBvcnRpbmcgbWF0aGVtYXRpY2FsIGNvbnRlbnQ8L2Rpdj48L2xpPjwvdWw+ZAIJDw8WAh8AZ2RkAhsPDxYCHwBnZGQCHQ8PFgIfAGdkZAIlDxYCHwBoZAILDw8WAh8CBScvc2NyaXB0L0FydGljbGVzL0FydGljbGUuYXNweD9haWQ9Mjc2ODFkZAIRDxYCHwYFCzIyIEFwciAyMDA5ZAITDw8WBB8GBQ5EZWVrc2hhIFNoZW5veR8CBSgvc2NyaXB0L01lbWJlcnNoaXAvVmlldy5hc3B4P21pZD0zODY2MDEwZGQCFQ8WAh8GBRhDb3B5cmlnaHQgMjAwOCBieSBIYW50b3VkZBwMZWfZUAmrj50kGxx8IwkQDkEI" type="hidden"> </div> <div> <input name="__EVENTVALIDATION" id="__EVENTVALIDATION" value="/wEWCAKbweL/BgLAlMXDBwLBlMXDBwLClMXDBwLDlMXDBwLElMXDBwLP+++tCwK5upDkCysC955w2IXKjsR2sd3bSplVn7r2" type="hidden"> </div> <h2>License</h2> <div id="ctl00_LicenseTerms"><p>This article, along with any associated source code and files, is licensed under <a href="http://www.codeproject.com/info/cpol10.aspx">The Code Project Open License (CPOL)</a></p></div> <h2>Download</h2><a style="color: rgb(51, 51, 255);" href="http://www.megaupload.com/?d=PCX7V6QR" target="_blank">Download sample application here</a><br /></form>Hantouhttp://www.blogger.com/profile/16364616567528044982noreply@blogger.com1tag:blogger.com,1999:blog-6947037657992916256.post-63388470901178472032009-04-15T13:12:00.017-04:002009-04-19T09:38:16.565-04:00Requirement Analysis<a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjKywC2T2YhBO21J_lJ5g3KQUeGarLoCpu48d7DygLB7m1D-ZkHwBDUrFAw2X78OwbYGBWxpQZLwNKsmBq2zZ4LmhKPehRsnk0TXwVgF9-4kjcZUXZT7l3TzriUmyrvz-JSftAFxyIb4Eo/s1600-h/Requirement+Analysis.jpg" target="_blank"><img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 400px; height: 300px;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjKywC2T2YhBO21J_lJ5g3KQUeGarLoCpu48d7DygLB7m1D-ZkHwBDUrFAw2X78OwbYGBWxpQZLwNKsmBq2zZ4LmhKPehRsnk0TXwVgF9-4kjcZUXZT7l3TzriUmyrvz-JSftAFxyIb4Eo/s400/Requirement+Analysis.jpg" alt="" id="BLOGGER_PHOTO_ID_5324970662078689682" border="0" /></a><br />I found this interesting picture picture yesterday and strongly feel that it exactly describe what I'm working on everyday! We all have stress from work, family, friends, etc. This funny cartoon is a way to relax myself just because someone has point out what I'm thinking daily.<br /><br />I actually found this cartoon from an IT forum. I search the picture on the Google and find that it has a full version of the 'Requirements Analysis' story. Here is the link for you interest: <a style="color: rgb(51, 102, 255);" href="http://www.projectcartoon.com/" target="_blank">The Project Cartoon</a>. There are up to 18 cell-pictures you can choose and make your own cartoon.<br /><br /><b style="font-style: italic;">Requirements analysis</b><span style="font-style: italic;"> in </span>systems engineering and software engineering, encompasses those tasks that go into determining the needs or conditions to meet for a new or altered product, taking account of the possibly conflicting requirements of the various stakeholders, <span style="font-style: italic;">such as beneficiaries or users</span>. -- <a style="color: rgb(51, 102, 255);" href="http://en.wikipedia.org/wiki/Requirements_analysis" target="_blank">Wiki</a>Hantouhttp://www.blogger.com/profile/16364616567528044982noreply@blogger.com0tag:blogger.com,1999:blog-6947037657992916256.post-17134009464801324862009-04-12T22:21:00.025-04:002009-04-22T16:27:52.658-04:008 Ways to Optimize Your C# Application 2/2<style type="text/css"> .style1 { color: #0000FF; } .style2 { color: #FF0000; } </style> <p><strong><span style="font-size:130%;">Ways to optimize C# code in .NET development</span></strong></p><p><strong></strong> <strong><span style="font-size:130%;">5. "try catch" vs "if else"</span></strong></p> <p>The "<span class="style2">try catch</span>" block is used to catch exceptions that are beyond our controls, such as connection problem. The "<span class="style2">if else</span>" is one of the basic logic which is being used in both programming and reality. The "try catch" block helps to avoid error-prone calls or any errors that might slow down the application. According to the '<b>KISS</b>' principle, using "try catch" to keep code "simple", "clean" better than using "if else" statements. However, we should refactor our source code to require less "try catch" or "if else" statements. That should be the main concentrate of code optimization.</p> <p> <strong><span style="font-size:130%;">6. Replace divisions</span></strong></p> <p> Although this issue is not as common as above, you could benifit from it if you are playing with numeric operations such as multiplication, division. The C# language is relatively slow when it comes to division operations. There is an article written by "<span class="style1">rob tillaart</span>" from CodeProject: <a href="http://www.codeproject.com/KB/cs/FindMulShift.aspx"> http://www.codeproject.com/KB/cs/FindMulShift.aspx</a>. He introduces an alternative way called "Multiply Shift" in C# to optimize the performance.</p> <p> <strong><span style="font-size:130%;">7. Using sealed classes when there isn't any derived class</span></strong></p> <p> The sealed modifier is primarily used to prevent unintended derivation, but it also enables certain run-time optimizations. In particular, because a sealed class is known to never have any derived classes, it is possible to transform virtual function member invocations on sealed class instances into non-virtual invocations. -- From "gicio" in '<a href="http://channel9.msdn.com/forums/TechOff/246514-Performance-Optimization-in-C/">Performance Optimization in C#</a>'</p><p> <strong><span style="font-size:130%;">8. 'for' Loop vs. 'foreach' Loop</span></strong></p> <p> Again, this is from "gicio" in '<a href="http://channel9.msdn.com/forums/TechOff/246514-Performance-Optimization-in-C/">Performance Optimization in C#</a>'.<br /> This code costs tooooo much: <br /> <span class="style2"></span></p><blockquote style="color: rgb(255, 0, 0);"><span class="style2"></span>foreach(DataRow currentDataRow in currentDataTable.Rows) <br /> { <br /> newDataTable.ImportRow(currentDataRow); <br /> }</blockquote> <br /> this code runs over 300 % faster (depends on rows count): <br /> <span class="style2"></span><span class="style2"></span><blockquote style="color: rgb(255, 0, 0);"><span class="style2"></span>DataRow[] allRows = currentDataTable.Select(); <br /> foreach (DataRow currentDataRow in allRows) <br /> { <br /> newDataTable.ImportRow(currentDataRow); <br />}<div style="text-align: left;"></div></blockquote><div style="text-align: left;"></div><p></p> <p> <strong><span style="font-size:130%;">Conclusion</span></strong></p> <p> As you can see these are very simple C# code optimizations and yet they can have a powerful impact on the performance of your application. If you know any other useful C# code optimization ideas, please let me know and I will add them to the list here.</p><p><a href="http://hantou.blogspot.com/2009/04/8-ways-to-optimize-your-c-application.html"><span style="color: rgb(51, 51, 255);">8 Ways to Optimize Your C# Application 1/2</span></a></p>Hantouhttp://www.blogger.com/profile/16364616567528044982noreply@blogger.com0tag:blogger.com,1999:blog-6947037657992916256.post-51365783300961607112009-04-09T16:03:00.073-04:002009-04-22T16:28:00.209-04:008 Ways to Optimize Your C# Application 1/2Ways to optimize C# code in .NET development<p></p>Stuck with your code? Need higher code performance?Code optimization is an important aspect of writing an efficient C# application for your .NET development. The following 8 tips will help you increase the efficiency of your C# applications.<br /><br /><p><strong><span style="font-size:130%;">1. StringBuilder: knowing when to use</span><br /></strong>The main difference between string and StringBuilder is that using the <span style="color: rgb(255, 0, 0);">StringBuilder</span> to modify a string without creating a new object can boost performance when concatenating many strings in a loop. If you have a loop that will make modification to a single string for many iterations, then a StringBuilder class is much faster than a string type. However, if you just want to append/insert something to a string, then a StringBuilder will be over power. In this case, a simple string type will work well.<br /></p><p><strong><span style="font-size:130%;">2. Strings Compare: Non-Case Sensitive<br /></span></strong>When we compare two strings, usually we use the built-in equals() method for the comparison. In case of ignoring the cases, people use <span style="color: rgb(255, 0, 0);">ToLower()</span> or <span style="color: rgb(255, 0, 0);">ToUpper()</span> methods. However, ToLower() or ToUpper() are bottlenecks in performance. Here is a way to increase your applications: use <span style="color: rgb(255, 0, 0);">string.Compare(str1, str2, true) == 0;</span> for comparing two strings ignoring cases. If <span style="color: rgb(255, 0, 0);">str1</span> and <span style="color: rgb(255, 0, 0);">str2</span> are equal ignoring cases then result will return 0.<br /></p><p><strong><span style="font-size:130%;">3. Strings Compare: "string.Empty "<br /></span></strong>It is normal to see people use <span style="color: rgb(255, 0, 0);">.equals("")</span> for comparing an empty string. A popular practice is that checking a string's length to be 0 is faster than comparing it to an empty string. Using <span style="color: rgb(255, 0, 0);">string.Empty</span> will not make anysignificant performance improvement, but bringing you the readable optimization.<br /></p><p><strong><span style="font-size:130%;">4. Using "List<>" instead of using "ArrayList"<br /></span></strong>Both <span class="style1">List<></span> and <span class="style1">ArrayList</span> can store objects within the same list. The difference is that <span class="style1">ArrayList</span> can store multiple types of objects while <span class="style1">List<></span> has to specify one type of object. Also, when you extract the object from the list, the List<> does not need to cast the variable to a proper type while ArrayList has to. Therefore, if<br />you are keeping the same type of variables in one ArrayList, you can gain a performance boost by using List<> instead.</p><p>(to be continue...)<br /><a href="http://hantou.blogspot.com/2009/04/8-ways-to-optimize-your-c-application_12.html"><span style="color: rgb(51, 51, 255);">8 Ways to Optimize Your C# Application 2/2</span></a></p>Hantouhttp://www.blogger.com/profile/16364616567528044982noreply@blogger.com2tag:blogger.com,1999:blog-6947037657992916256.post-45755805914093418502009-04-07T10:31:00.038-04:002009-04-27T10:56:40.403-04:00Add a property to user control<span style="font-family:georgia;">The .NET Framework has extensive support for programmers to create custom user controls. When you create a user control, also known as custom control, you can add a custom property to the property page that allow the user to modify the properties you created. Let's take a look at how to achieve this goal step-by-step:</span><strong style="font-family: arial;"><br /><br />Known issues</strong><span style="font-family:georgia;">:</span><br /><span style="font-family:georgia;">Assume that we create a winform project and a user control which contains a button only. This user control is called "MyUserButton.cs". We want to add a custom property called "TreeView" that should appear on the "Properties" panel.</span><strong style="font-family: arial;"><br /><br />Detail</strong><span style="font-family:georgia;">:</span><br /><span style="font-family:georgia;">1. In the Solution Explorer panel, right click on your user control "MyUserButton.cs" file and select "View Code".</span><span style="font-family:georgia;"><br /><br />2. In the class "MyUserButton.cs", create a private variable "treeView" with type "TreeView".</span><br /><br /><em style="font-family:georgia;"><span style="color: rgb(204, 51, 204);"><span style="color: rgb(255, 0, 0);">private TreeView treeView;</span></span></em><span style="font-family:georgia;"><span style="color: rgb(255, 102, 102);"><br /></span><br />3. Then type the following code beneath the variable declarations from last step:</span><br /><br /><em style="font-family:georgia;"><span style="color: rgb(204, 102, 204);"><span style="color: rgb(255, 0, 0);">public TreeView MyTreeView</span><br /><span style="color: rgb(255, 0, 0);">{<br />get { return treeView; }<br />set { treeView = value; }<br />}</span></span></em><span style="font-family:georgia;"><br /><br />4. Save the file and add the "MyUserButton" control to the main window. On the Properties grid panel we can find a property named "TreeView" that is what we just created.</span><strong style="font-family: arial;"><br /><br />Summary</strong><br /><span style="font-family:georgia;">There are some more advance features about adding a property to the user control. Here is just a simple example that giving you a brief idea on it. For more information, the article "</span><a style="font-family: arial;" href="http://support.microsoft.com/kb/197127" target="_blank">How To Add a Custom Font Property</a><span style="font-family:georgia;"> to a User Control" is also useful.</span>Hantouhttp://www.blogger.com/profile/16364616567528044982noreply@blogger.com0