<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-15836190</id><updated>2012-02-16T13:05:09.578-08:00</updated><title type='text'>For Those Who Matter</title><subtitle type='html'></subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://forthosewhomatters.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/15836190/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://forthosewhomatters.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><link rel='next' type='application/atom+xml' href='http://www.blogger.com/feeds/15836190/posts/default?start-index=101&amp;max-results=100'/><author><name>For Those Who Matter</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>101</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-15836190.post-4161511848547957969</id><published>2012-01-11T06:55:00.001-08:00</published><updated>2012-01-11T06:55:03.680-08:00</updated><title type='text'>Install / Uninstall .NET Windows Service [C#]</title><content type='html'>Install service using InstallUtil.exeTo install or uninstall windows service (which was created using .NET Framework) use utility InstallUtil.exe. This tool can be found in the following path (use appropriate framework version number).C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\InstallUtil.exeTo install .NET service run command similar to this (specify full path to your service).InstallUtil.exe "c:\myservice.exe"To uninstall .NET service use the same command with parameter /u.InstallUtil.exe /u "c:\myservice.exe"Install service programmaticallyTo install service programmatically using C# see the following class ServiceInstaller in c-sharpcorner.com article.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/15836190-4161511848547957969?l=forthosewhomatters.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://forthosewhomatters.blogspot.com/feeds/4161511848547957969/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=15836190&amp;postID=4161511848547957969' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/15836190/posts/default/4161511848547957969'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/15836190/posts/default/4161511848547957969'/><link rel='alternate' type='text/html' href='http://forthosewhomatters.blogspot.com/2012/01/install-uninstall-net-windows-service-c.html' title='Install / Uninstall .NET Windows Service [C#]'/><author><name>For Those Who Matter</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-15836190.post-8921431601583621920</id><published>2011-12-22T10:41:00.000-08:00</published><updated>2011-12-22T10:52:29.030-08:00</updated><title type='text'>EBCIDIC vs ASCII</title><content type='html'>Mainframes use the EBCDIC code set, while PCs use the ASCII codeset.  The codeset refers to how the alphabet is coded internally in the computer. Each letter of the alphabet is represented by a value, and the EBCDIC and ASCII codesets assign different values to the alphabet. For example, the letter A is represented by the hexadecimal (hex) value 41 (65 decimal) in the ASCII codeset, and by the hex value C1 (193 decimal) in the EBCDIC code set.&lt;br /&gt;&lt;br /&gt;In SQL, you can use "COLLATE SQL_EBCDIC037_CP1_CS_AS" to hint the SQL to use EBCDIC system to compare. The collate hint should be applied to the left of a comparision. For example,&lt;br /&gt;&lt;br /&gt;If 'A' COLLATE SQL_EBCDIC037_CP1_CS_AS  &gt; 'a'&lt;br /&gt;Print 'ok';&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;If 'A2222' COLLATE SQL_EBCDIC037_CP1_CS_AS Between 'Aaaaa' And 'A0000'&lt;br /&gt;Print 'ok';&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/15836190-8921431601583621920?l=forthosewhomatters.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://forthosewhomatters.blogspot.com/feeds/8921431601583621920/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=15836190&amp;postID=8921431601583621920' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/15836190/posts/default/8921431601583621920'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/15836190/posts/default/8921431601583621920'/><link rel='alternate' type='text/html' href='http://forthosewhomatters.blogspot.com/2011/12/ebcidic-vs-ascii.html' title='EBCIDIC vs ASCII'/><author><name>For Those Who Matter</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-15836190.post-3166605120489228137</id><published>2011-01-17T06:23:00.000-08:00</published><updated>2011-01-17T06:24:29.563-08:00</updated><title type='text'>X509 certificate - Key distribution and authentication (how it works)</title><content type='html'>These technologies use an X.509 certificate hierarchy with public-key cryptography to accomplish two tasks- Key Distribution and User Authentication. &lt;br /&gt;&lt;br /&gt;Here is a simplified version of how this works: A public/private keypair (usually RSA) is generated by a CA. All private keys must be safeguarded by their owner against compromise. Public keys are incorporated into a certificate, which is a binding between an X.500 hierarchical name identity and a public key. Public keys (and likewise, certificates) do not need to be protected from disclosure to unauthorized parties (a.k.a. compromise), and can be distributed with software or by insecure electronic means, such as web sites, information servers, etc. &lt;br /&gt;&lt;br /&gt;A user wishing to acquire an X.509 certificate also creates a keypair, safeguarding his private key. The public key is incorporated into a "certificate request", which is usually an email message to the CA requesting identity verification and the issuance of a certificate. &lt;br /&gt;&lt;br /&gt;If approved, the CA returns to the user a certificate, signed by the CA. A signed certificate is simply the user's public key and X.509 identity encrypted with the CA's private key. Anyone who has access to a copy of the CA's certificate can verify the authenticity of the user's certificate by decrypting the user's certificate with the public key contained in the CA's certficate. Again, the actual implementation is more complicated, but here is a simplified version of how two entities perform mutual authentication: Both the client and server have valid copies of the issuing CA's certificate. A client informs the server that it wishes to mutually authenticate, so the parties exchange certificates Each party verifies the authenticity of the certificate by decrypting the infomation in the certificate with the public key of the CA. The server can then send some value to the client, encrypted with the public key of the client. Only the client can decrypt the ciphertext and read the value. The client performs a transformation of the value, and encrypts the result with the public key of the server and returns this information. Once the parties are satisfied as to the identity of the other party, it is possible to establish a secure connection between the client and server by negotiating a session key and security. Globus (and therefore, Condor) do not perform this final step of establishing a secure connection because of cryptographic export controls.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/15836190-3166605120489228137?l=forthosewhomatters.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://forthosewhomatters.blogspot.com/feeds/3166605120489228137/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=15836190&amp;postID=3166605120489228137' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/15836190/posts/default/3166605120489228137'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/15836190/posts/default/3166605120489228137'/><link rel='alternate' type='text/html' href='http://forthosewhomatters.blogspot.com/2011/01/x509-certificate-key-distribution-and.html' title='X509 certificate - Key distribution and authentication (how it works)'/><author><name>For Those Who Matter</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-15836190.post-7110888134041714960</id><published>2011-01-16T14:21:00.000-08:00</published><updated>2011-01-16T14:22:30.920-08:00</updated><title type='text'>ASP.net permissions to root certificate store</title><content type='html'>Generally you give permissions to A certificate. I use a method like this to find the custom made cert and grant permissions. If you are using a cert issued by a public entity like Verisign, Thawte, etc, this is probably unnecessary.&lt;br /&gt;&lt;br /&gt;FindPrivateKey.exe My LocalMachine –n "CN=&lt;certificate issuer&gt;" ...will find certificates on the local machine in the personal store for a particular issuer. &lt;br /&gt;&lt;br /&gt;Note: If FindPrivateKey is not on your local machine, download the WCF samples, including the FindPrivateKey tool, at http://www.microsoft.com/downloads/details.aspx?FamilyId=2611A6FF-FD2D-4F5B-A672-C002F1C09CCD&amp;displaylang=en &lt;br /&gt;&lt;br /&gt;FindPrivateKey returns the location of the private key for the certificate, similar to &lt;br /&gt;&lt;br /&gt;"C:\Documents and Settings\All Users\Application Data\Microsoft\Crypto\RSA\Machinekeys\4d657b73466481beba7b0e1b5781db81_c225a308-d2ad-4e58-91a8-6e87f354b030". Run the following command line to assign read only access permissions to the process identity of the ASP.NET/WCF Service&lt;br /&gt;&lt;br /&gt;cacls.exe "C:\Documents and Settings\All Users\Application Data\Microsoft\Crypto\RSA\Machinekeys\4d657b73466481beba7b0e1b5781db81_c225a308-d2ad-4e58-91a8-6e87f354b030" /E /G "NT AUTHORITY\NETWORK SERVICE":R NOTE: If you are running Microsoft Windows® XP, give the certificate permissions for the ASPNET identity instead of the NT Authority\Network Service identity, because the IIS process runs under the ASPNET account in Windows XP.&lt;br /&gt;&lt;br /&gt;Certificates are viewable from the MMC snap in for Certificates. Open MMC, choose File --&gt; Add/Remove Snap in, click the add button and choose certificates. From here you will need to choose the appropriate store (usually Computer Account - Local Computer for ASP.NET items) to manage and then you can view/admin the certs. &lt;br /&gt;&lt;br /&gt;Please take a good hard look at the different command line options, and make sure that you have a clear understanding of what certificates are and how they work before granting any permissions.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/15836190-7110888134041714960?l=forthosewhomatters.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://forthosewhomatters.blogspot.com/feeds/7110888134041714960/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=15836190&amp;postID=7110888134041714960' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/15836190/posts/default/7110888134041714960'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/15836190/posts/default/7110888134041714960'/><link rel='alternate' type='text/html' href='http://forthosewhomatters.blogspot.com/2011/01/aspnet-permissions-to-root-certificate.html' title='ASP.net permissions to root certificate store'/><author><name>For Those Who Matter</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-15836190.post-6682673588554760705</id><published>2011-01-13T18:56:00.000-08:00</published><updated>2011-01-17T06:13:40.548-08:00</updated><title type='text'>create test certificate</title><content type='html'>http://blog.functionalfun.net/2008/05/how-to-create-server-certificate-for.html&lt;br /&gt;&lt;br /&gt;http://www.devproconnections.com/article/security-development/working-with-certificates.aspx&lt;br /&gt;&lt;br /&gt;How to debug and send certificates in .net &lt;br /&gt;http://www.kerrywong.com/2006/12/01/using-x509-certificate-with-web-service-in-aspnet/&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/15836190-6682673588554760705?l=forthosewhomatters.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://forthosewhomatters.blogspot.com/feeds/6682673588554760705/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=15836190&amp;postID=6682673588554760705' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/15836190/posts/default/6682673588554760705'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/15836190/posts/default/6682673588554760705'/><link rel='alternate' type='text/html' href='http://forthosewhomatters.blogspot.com/2011/01/create-test-certificate.html' title='create test certificate'/><author><name>For Those Who Matter</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-15836190.post-6286134580999502162</id><published>2011-01-13T13:34:00.001-08:00</published><updated>2011-01-13T13:34:52.932-08:00</updated><title type='text'>How can I start the Certificate Manager on Windows XP?</title><content type='html'>The certificate manager is implemented as a Management Console Snap-in Control (MSC) file. The application can be started as certmgr.msc &lt;br /&gt;&lt;br /&gt;Below is a list of other management console Snap-in controls. They are all in \Windows\System32 &lt;br /&gt;&lt;br /&gt;You can start them from the start menu, by clicking on 'run' and then entering the desired command, e.g. certmgr.msc.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/15836190-6286134580999502162?l=forthosewhomatters.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://forthosewhomatters.blogspot.com/feeds/6286134580999502162/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=15836190&amp;postID=6286134580999502162' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/15836190/posts/default/6286134580999502162'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/15836190/posts/default/6286134580999502162'/><link rel='alternate' type='text/html' href='http://forthosewhomatters.blogspot.com/2011/01/how-can-i-start-certificate-manager-on.html' title='How can I start the Certificate Manager on Windows XP?'/><author><name>For Those Who Matter</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-15836190.post-1798199472900498753</id><published>2011-01-12T12:27:00.000-08:00</published><updated>2011-01-12T12:28:13.161-08:00</updated><title type='text'>How browser verify SSL certificate</title><content type='html'>&lt;strong&gt;What is browser compatibility?&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;The certificate that you purchase to secure your web site must be digitally signed by another certificate that is already in the trusted store of your user's web browsers. By doing this, the web browser will automatically trust your certificate because it is issued by someone that it already trusts. If it isn't signed by a trusted root certificate, or if links in the certificate chain are missing, then the web browser will give a warning message that the web site may not be trusted.&lt;br /&gt;&lt;br /&gt;So browser compatibility means that the certificate you buy is signed by a root certificate that is already trusted by most web browsers that your customers may be using. Unless otherwise noted, the certificates from all major certificate providers listed on SSL Shopper are compatible with 99% of all browsers. For more details about a specific certificate provider, see SSL Certificate Compatibility.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/15836190-1798199472900498753?l=forthosewhomatters.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://forthosewhomatters.blogspot.com/feeds/1798199472900498753/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=15836190&amp;postID=1798199472900498753' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/15836190/posts/default/1798199472900498753'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/15836190/posts/default/1798199472900498753'/><link rel='alternate' type='text/html' href='http://forthosewhomatters.blogspot.com/2011/01/how-browser-verify-ssl-certificate.html' title='How browser verify SSL certificate'/><author><name>For Those Who Matter</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-15836190.post-7903092644020841342</id><published>2010-12-31T12:13:00.000-08:00</published><updated>2010-12-31T12:20:08.145-08:00</updated><title type='text'>How does ASP.NET know a session has been authorized?</title><content type='html'>The server looks for an authentication cookie. If it fails to find the authentication cookie, the user is redirected to the configured logon page (Login.aspx), as specified by the LoginUrl attribute of the forms element.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;The FormsAuthentication class creates the authentication cookie automatically when the FormsAuthentication.SetAuthCookie or FormsAuthentication.RedirectFromLoginPage methods are called.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;If your application is configured to use cookieless forms authentication and the FormsAuthentication.RedirectFromLoginPage method is being used, then the FormsAuthenticationModule class automatically sets the forms authentication ticket in the URL.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/15836190-7903092644020841342?l=forthosewhomatters.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://forthosewhomatters.blogspot.com/feeds/7903092644020841342/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=15836190&amp;postID=7903092644020841342' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/15836190/posts/default/7903092644020841342'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/15836190/posts/default/7903092644020841342'/><link rel='alternate' type='text/html' href='http://forthosewhomatters.blogspot.com/2010/12/how-does-aspnet-know-session-has-been.html' title='How does ASP.NET know a session has been authorized?'/><author><name>For Those Who Matter</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-15836190.post-1440501288411626235</id><published>2010-11-23T07:23:00.000-08:00</published><updated>2010-11-23T07:24:51.326-08:00</updated><title type='text'>Show CONNECTION tab in IE</title><content type='html'>[HKEY_CURRENT_USER\Software\Policies\Microsoft\Internet Explorer\Control Panel]"ConnectionsTab"=dword:00000000&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;OR &lt;br /&gt;&lt;br /&gt;[HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Internet Explorer\Control Panel]"ConnectionsTab"=dword:00000000&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/15836190-1440501288411626235?l=forthosewhomatters.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://forthosewhomatters.blogspot.com/feeds/1440501288411626235/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=15836190&amp;postID=1440501288411626235' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/15836190/posts/default/1440501288411626235'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/15836190/posts/default/1440501288411626235'/><link rel='alternate' type='text/html' href='http://forthosewhomatters.blogspot.com/2010/11/show-connection-tab-in-ie.html' title='Show CONNECTION tab in IE'/><author><name>For Those Who Matter</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-15836190.post-8868327557890906919</id><published>2010-09-16T09:34:00.000-07:00</published><updated>2010-09-16T09:36:20.927-07:00</updated><title type='text'>Creating/Using a Microsoft Data Link (.udl) File</title><content type='html'>To create a .udl file: &lt;br /&gt;&lt;br /&gt;1. Create an empty text file with the extension .udl. &lt;br /&gt;&lt;br /&gt;2. From Windows Explorer, double-click on your new file to open the Data Link &lt;br /&gt;&lt;br /&gt;3. In the Data Link Properties dialog box, enter the connection information that is required to open an ADO Connection object. &lt;br /&gt;&lt;br /&gt;4. Click OK to save the .udl file with the information that you entered. &lt;br /&gt;&lt;br /&gt;Sample Code That Shows How to Reference the File &lt;br /&gt;&lt;br /&gt;The following sample code shows you how to reference the file in the ConnectionString property of a Connection object. It requires that you reference the Microsoft ActiveX Data Objects Library.&lt;br /&gt;&lt;br /&gt;   Dim obConnection As New ADODB.Connection&lt;br /&gt;   obConnection.ConnectionString = "File Name=c:\mydir\myfile.udl"   &lt;br /&gt;   obConnection.Open&lt;br /&gt;&lt;br /&gt;Note: You can also refer to the .udl file in the Visual Basic DataEnvironment tool.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/15836190-8868327557890906919?l=forthosewhomatters.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://forthosewhomatters.blogspot.com/feeds/8868327557890906919/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=15836190&amp;postID=8868327557890906919' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/15836190/posts/default/8868327557890906919'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/15836190/posts/default/8868327557890906919'/><link rel='alternate' type='text/html' href='http://forthosewhomatters.blogspot.com/2010/09/creatingusing-microsoft-data-link-udl.html' title='Creating/Using a Microsoft Data Link (.udl) File'/><author><name>For Those Who Matter</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-15836190.post-7527545996330000532</id><published>2010-09-01T07:38:00.000-07:00</published><updated>2010-09-01T07:39:37.271-07:00</updated><title type='text'>Register WCF with IIS</title><content type='html'>In order to host a WCF service in IIS, WCF should be registered correctly with IIS. If you install .Net 3 (or 3.5) after IIS this will happen automatically; however, if you install IIS on a system which already containz .Net 3 then a manual registration for WCF is needed as explain by (http://msdn.microsoft.com/en-us/library/aa751792.aspx)&lt;br /&gt;&lt;br /&gt;You need to run command prompt as administrator, and run the following command - &lt;br /&gt;&lt;br /&gt;"%windir%\Microsoft.NET\Framework\v3.0\Windows Communication Foundation\ServiceModelReg.exe" -r -y&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/15836190-7527545996330000532?l=forthosewhomatters.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://forthosewhomatters.blogspot.com/feeds/7527545996330000532/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=15836190&amp;postID=7527545996330000532' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/15836190/posts/default/7527545996330000532'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/15836190/posts/default/7527545996330000532'/><link rel='alternate' type='text/html' href='http://forthosewhomatters.blogspot.com/2010/09/register-wcf-with-iis.html' title='Register WCF with IIS'/><author><name>For Those Who Matter</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-15836190.post-1866680110086074175</id><published>2010-07-13T11:16:00.000-07:00</published><updated>2010-07-13T11:17:10.431-07:00</updated><title type='text'>Convert Excel to DataSet</title><content type='html'>public static DataSet ConvertExcelToDataSet(string sFileFullPath, string sSheetName, string tableName, bool bCleanupTable)&lt;br /&gt;        {&lt;br /&gt;            OleDbConnection conn = null;&lt;br /&gt;&lt;br /&gt;            try&lt;br /&gt;            {&lt;br /&gt;                sFileFullPath = GetFileFullPath();&lt;br /&gt;&lt;br /&gt;                DataSet oDataSet = new DataSet();&lt;br /&gt;&lt;br /&gt;                string dsn = @"Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + sFileFullPath + @";Extended Properties=""Excel 8.0;HDR=" + (bCleanupTable ? "NO" : "YES") + @";IMEX=1""";&lt;br /&gt;                conn = new OleDbConnection(dsn);&lt;br /&gt;                conn.Open();&lt;br /&gt;                OleDbDataAdapter adapter = new OleDbDataAdapter("SELECT * FROM [" + sSheetName + "$]", conn);&lt;br /&gt;&lt;br /&gt;                adapter.FillSchema(oDataSet, SchemaType.Source, tableName);&lt;br /&gt;&lt;br /&gt;                foreach (DataColumn column in oDataSet.Tables[tableName].Columns)&lt;br /&gt;                    column.DataType = typeof(string);&lt;br /&gt;&lt;br /&gt;                adapter.Fill(oDataSet, tableName);&lt;br /&gt;&lt;br /&gt;                DataTable table = oDataSet.Tables[tableName];&lt;br /&gt;                if (bCleanupTable)&lt;br /&gt;                    CleanupExcelData(table);&lt;br /&gt;&lt;br /&gt;                return oDataSet;&lt;br /&gt;            }&lt;br /&gt;            finally&lt;br /&gt;            {&lt;br /&gt;                if (conn != null)&lt;br /&gt;                    conn.Close();&lt;br /&gt;            }&lt;br /&gt;        }&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/15836190-1866680110086074175?l=forthosewhomatters.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://forthosewhomatters.blogspot.com/feeds/1866680110086074175/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=15836190&amp;postID=1866680110086074175' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/15836190/posts/default/1866680110086074175'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/15836190/posts/default/1866680110086074175'/><link rel='alternate' type='text/html' href='http://forthosewhomatters.blogspot.com/2010/07/convert-excel-to-dataset.html' title='Convert Excel to DataSet'/><author><name>For Those Who Matter</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-15836190.post-4431721171848579996</id><published>2010-06-23T12:42:00.000-07:00</published><updated>2010-06-23T12:49:49.454-07:00</updated><title type='text'>Microsoft Web Server Clustering</title><content type='html'>WLBS (Windows NT Load Balancing Service) is used in Windows NT 4.0&lt;br /&gt;&lt;br /&gt;NLB  (Network Loading Balancing) is included in the Windows Server 2003 family, Windows 2000 Standard Server SP 3 and later, Windows 2000 Advanced Server, and Windows 2000 Datacenter Server.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/15836190-4431721171848579996?l=forthosewhomatters.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://forthosewhomatters.blogspot.com/feeds/4431721171848579996/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=15836190&amp;postID=4431721171848579996' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/15836190/posts/default/4431721171848579996'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/15836190/posts/default/4431721171848579996'/><link rel='alternate' type='text/html' href='http://forthosewhomatters.blogspot.com/2010/06/microsoft-web-server-clustering.html' title='Microsoft Web Server Clustering'/><author><name>For Those Who Matter</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-15836190.post-8030706545472930729</id><published>2010-01-19T09:38:00.001-08:00</published><updated>2010-01-19T09:38:52.194-08:00</updated><title type='text'>Search Key Words in the Stored Procedures</title><content type='html'>SELECT ROUTINE_NAME, ROUTINE_DEFINITION &lt;br /&gt;    FROM INFORMATION_SCHEMA.ROUTINES &lt;br /&gt;    WHERE ROUTINE_DEFINITION LIKE '%keywords%' &lt;br /&gt;    AND ROUTINE_TYPE='PROCEDURE'&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/15836190-8030706545472930729?l=forthosewhomatters.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://forthosewhomatters.blogspot.com/feeds/8030706545472930729/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=15836190&amp;postID=8030706545472930729' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/15836190/posts/default/8030706545472930729'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/15836190/posts/default/8030706545472930729'/><link rel='alternate' type='text/html' href='http://forthosewhomatters.blogspot.com/2010/01/search-key-words-in-stored-procedures.html' title='Search Key Words in the Stored Procedures'/><author><name>For Those Who Matter</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-15836190.post-5180874176722779235</id><published>2010-01-16T05:56:00.000-08:00</published><updated>2010-01-16T05:57:38.951-08:00</updated><title type='text'>Visual Studio 2005 ToolBox not showing Reporting Services tools</title><content type='html'>"Try rebuilding your toolbox items.  &lt;br /&gt;&lt;br /&gt;Locate the directory %USERPROFILE%\Local Settings\Application Data\Microsoft\VisualStudio\8.0 and delete the four (hidden) files: toolbox.tbd, toolbox_reset.tbd, toolboxIndex.tbd, toolboxIndex_reset.tbd.  Start VS and open the toolbox (This will take a while).  Note: You lose all user-added items from the toolbox.&lt;br /&gt;"&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/15836190-5180874176722779235?l=forthosewhomatters.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://forthosewhomatters.blogspot.com/feeds/5180874176722779235/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=15836190&amp;postID=5180874176722779235' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/15836190/posts/default/5180874176722779235'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/15836190/posts/default/5180874176722779235'/><link rel='alternate' type='text/html' href='http://forthosewhomatters.blogspot.com/2010/01/visual-studio-2005-toolbox-not-showing.html' title='Visual Studio 2005 ToolBox not showing Reporting Services tools'/><author><name>For Those Who Matter</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-15836190.post-4720004048412078600</id><published>2009-11-25T10:34:00.000-08:00</published><updated>2009-11-25T10:36:30.862-08:00</updated><title type='text'>ADO.NET Query Execution time is 10 times slower than via Query Analyzer</title><content type='html'>Try cleaning out procedure cache and memory buffers in QA&lt;br /&gt;&lt;strong&gt;DBCC DROPCLEANBUFFERS&lt;br /&gt;DBCC FREEPROCCACHE&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;Doing so before you test your query in QA prevents usage of cached execution plans and previous results cache.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/15836190-4720004048412078600?l=forthosewhomatters.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://forthosewhomatters.blogspot.com/feeds/4720004048412078600/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=15836190&amp;postID=4720004048412078600' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/15836190/posts/default/4720004048412078600'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/15836190/posts/default/4720004048412078600'/><link rel='alternate' type='text/html' href='http://forthosewhomatters.blogspot.com/2009/11/adonet-query-execution-time-is-10-times.html' title='ADO.NET Query Execution time is 10 times slower than via Query Analyzer'/><author><name>For Those Who Matter</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-15836190.post-3422989306447732455</id><published>2009-11-24T12:38:00.000-08:00</published><updated>2009-11-24T12:39:36.826-08:00</updated><title type='text'>MS SQL DB - Make it Case Insensitive</title><content type='html'>ALTER DATABASE MyDatabase&lt;br /&gt;COLLATE SQL_Latin1_General_CP1_CI_AS&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/15836190-3422989306447732455?l=forthosewhomatters.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://forthosewhomatters.blogspot.com/feeds/3422989306447732455/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=15836190&amp;postID=3422989306447732455' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/15836190/posts/default/3422989306447732455'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/15836190/posts/default/3422989306447732455'/><link rel='alternate' type='text/html' href='http://forthosewhomatters.blogspot.com/2009/11/ms-sql-db-make-it-case-insensitive.html' title='MS SQL DB - Make it Case Insensitive'/><author><name>For Those Who Matter</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-15836190.post-7622588368774611979</id><published>2009-10-08T07:58:00.001-07:00</published><updated>2009-10-08T07:58:47.209-07:00</updated><title type='text'>Run the CMD as a delegate user account</title><content type='html'>runas /user:bnysecurities\zhangh cmd&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/15836190-7622588368774611979?l=forthosewhomatters.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://forthosewhomatters.blogspot.com/feeds/7622588368774611979/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=15836190&amp;postID=7622588368774611979' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/15836190/posts/default/7622588368774611979'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/15836190/posts/default/7622588368774611979'/><link rel='alternate' type='text/html' href='http://forthosewhomatters.blogspot.com/2009/10/run-cmd-as-delegate-user-account.html' title='Run the CMD as a delegate user account'/><author><name>For Those Who Matter</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-15836190.post-807881440268814000</id><published>2009-10-02T07:42:00.000-07:00</published><updated>2009-10-02T07:43:49.151-07:00</updated><title type='text'>Where does ASPState Database store data?</title><content type='html'>The default when creating the ASPState database with the command line tool, aspnet_regsql, is for data to be stored in the tempdb rather than in the ASPState db. &lt;br /&gt;&lt;br /&gt;For others similarly unenlightened as I was: &lt;br /&gt;&lt;br /&gt;C:\&gt;aspnet_regsql -S servername -E -ssadd -sstype t&lt;br /&gt;&lt;br /&gt;is for the temdb option, and:&lt;br /&gt;&lt;br /&gt;C:\&gt;aspnet_regsql -S servername -E -ssadd -sstype p&lt;br /&gt;&lt;br /&gt;is for the persistent option.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/15836190-807881440268814000?l=forthosewhomatters.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://forthosewhomatters.blogspot.com/feeds/807881440268814000/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=15836190&amp;postID=807881440268814000' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/15836190/posts/default/807881440268814000'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/15836190/posts/default/807881440268814000'/><link rel='alternate' type='text/html' href='http://forthosewhomatters.blogspot.com/2009/10/where-does-aspstate-database-store-data.html' title='Where does ASPState Database store data?'/><author><name>For Those Who Matter</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-15836190.post-4700813511251148026</id><published>2009-09-10T08:58:00.000-07:00</published><updated>2009-09-10T09:07:38.727-07:00</updated><title type='text'>LARGEADDRESSAWARE and Visual Studio</title><content type='html'>To make the application use more than 2G memory, you need use LARGEADDRESSAWARE indicator when compiling.&lt;br /&gt;&lt;br /&gt;To make Visual Studio large address aware:&lt;br /&gt;&lt;br /&gt;1.Be sure to backup devenv.exe &lt;br /&gt;2.Using the Visual Studio command prompt, navigate to C:\Program Files\Microsoft Visual Studio 9\Common7\IDE\ &lt;br /&gt;3.execute the following command: &lt;br /&gt;   1:  editbin /LARGEADDRESSAWARE devenv.exe&lt;br /&gt;&lt;br /&gt;By doing above, your studio will be able to use more than 2G memory.&lt;br /&gt;&lt;br /&gt;In addition, "editbin /LARGEADDRESSAWARE " can be used against any managed assemblies. It will enable the assemblies use more than 2G memory.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/15836190-4700813511251148026?l=forthosewhomatters.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://forthosewhomatters.blogspot.com/feeds/4700813511251148026/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=15836190&amp;postID=4700813511251148026' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/15836190/posts/default/4700813511251148026'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/15836190/posts/default/4700813511251148026'/><link rel='alternate' type='text/html' href='http://forthosewhomatters.blogspot.com/2009/09/largeaddressaware-and-visual-studio.html' title='LARGEADDRESSAWARE and Visual Studio'/><author><name>For Those Who Matter</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-15836190.post-5030613103482460922</id><published>2009-09-10T08:35:00.000-07:00</published><updated>2009-09-10T08:36:38.681-07:00</updated><title type='text'>3GB Switch in Windows boot.ini</title><content type='html'>http://www.maxi-pedia.com/3GB+switch+Windows+boot.ini+3+GB&lt;br /&gt;&lt;br /&gt;The /3GB or 3GB switch in the boot.ini file lets you tune the use of memory and memory address space in your computer. The /3GB switch specifies the amount of memory for user-mode virtual address space. It is used to allocate more memory to applications and less memory to the operating system.&lt;br /&gt;&lt;br /&gt;The /3GB switch increases the size of the user process address space from 2 GB to 3 GB. &lt;br /&gt;&lt;br /&gt;This can improve performance of servers that run virtual-memory-intensive applications. That is for example database servers. A larger address space can improve a database server performance.&lt;br /&gt;&lt;br /&gt;How does the /3GB switch work?&lt;br /&gt;By default Windows provides applications with a flat 32-bit virtual address space that describes 4 gigabytes of virtual memory. In other words, regardless of the amount of physical memory in your system (RAM), 32-bit versions of Windows only use a virtual address space of 4 GB.&lt;br /&gt;&lt;br /&gt;The address space is split so that 2 GB of address space is directly accessible to user-mode processes (applications, for example your Opera Browser and the other 2 GB is only accessible to kernel-mode processes (Windows operating system, drivers, etc.).&lt;br /&gt;&lt;br /&gt;The 32-bit versions of Windows were later in their production cycles improved to provide applications with a 3 GB flat virtual address space, with the kernel and executive components using only 1 GB.&lt;br /&gt;&lt;br /&gt;This is accomplished by adding the /3GB switch to the boot.ini file. Adding the /3GB switch to the boot.ini file will not increase the amount of physical RAM memory, the 3GB switch just tells the computer to allocate the existing memory space differently.&lt;br /&gt;&lt;br /&gt;The 3GB boot.ini switch is often used on Windows Server 2003 which includes support for the 3GB startup switch.&lt;br /&gt;&lt;br /&gt;What is the benefit of using the 3GB switch?&lt;br /&gt;Depending on what software you run on your server, it might make sense to optimize the server memory usage. If for example you are running only a few memory extensive large applications that do not interact with the operating system but rather work on their own, you might want to consider implementing this switch.&lt;br /&gt;&lt;br /&gt;The additional virtual address space that you give applications with the 3GB switch helps reduce the amount of memory fragmentation in the virtual address space.&lt;br /&gt;&lt;br /&gt;What values can the /3GB switch take?&lt;br /&gt;The switch can have any value between 2048 (2 GB) and 3072 (3 GB) megabytes. It needs to be expressed in decimal notation.&lt;br /&gt;&lt;br /&gt;With the switch, Windows will use the remaining address space (4 GB minus the specified amount) as its kernel-mode address space. &lt;br /&gt;&lt;br /&gt;How do I find out what boot.ini options my server uses?&lt;br /&gt;You can see this in the boot.ini file, of course. Another more detailed way is to research registry settings. In this case, you would go to the Start menu, click Run, type REGEDIT, and hit ENTER.&lt;br /&gt;&lt;br /&gt;Locate the following registry keys section:&lt;br /&gt;&lt;br /&gt;HKLM\System\CurrentControlSet\Control\SystemStartOptions&lt;br /&gt;&lt;br /&gt;How do I set the /3GB switch in Windows Server 2003?&lt;br /&gt;Setting the /3GB switch for your server is very easy. Execute the following steps:&lt;br /&gt;&lt;br /&gt;-&gt; right-click My Computer&lt;br /&gt;-&gt; Properties&lt;br /&gt;-&gt; click the Advanced tab&lt;br /&gt;-&gt; click Settings in the Startup and Recovery area&lt;br /&gt;-&gt; click Edit in the System startup area&lt;br /&gt;&lt;br /&gt;This will open the Windows boot.ini file in Notepad.  See the following print screen:&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Locate the [Operating Systems] section and add the /3GB switch to the end of the startup line that includes the /fastdetect. Now you can save the changes, close Notepad, and click OK to close all the open dialog boxes.&lt;br /&gt;&lt;br /&gt;You need to restart the computer for the change to take effect.&lt;br /&gt;&lt;br /&gt;Boot.ini file /3GB switch example&lt;br /&gt;This is what your default boot.ini file before you make the change might look like. The timeout and partition and other parameters depend on your setup. Pay attention to the line with the /fastdetect.&lt;br /&gt;&lt;br /&gt;[boot loader]timeout=10default=multi(0)disk(0)rdisk(0)partition(1)\WINDOWS[operating systems]multi(0)disk(0)rdisk(0)partition(1)\WINDOWS="Windows Server 2003, Enterprise" /fastdetectAnd, below you can find what the boot.ini file should look like after making the change.&lt;br /&gt;&lt;br /&gt;[boot loader]timeout=10default=multi(0)disk(0)rdisk(0)partition(1)\WINDOWS[operating systems]multi(0)disk(0)rdisk(0)partition(1)\WINDOWS="Windows Server 2003, Enterprise" /fastdetectmulti(0)disk(0)rdisk(0)partition(1)\WINDOWS="Windows Server 2003, Enterprise with /3GB" /3GB /fastdetectMake sure you do not enter a typo in this file as it might result in being unable to start your computer.&lt;br /&gt;&lt;br /&gt;Do I need to reboot the server after adding the /3GB switch?&lt;br /&gt;Yes, the /3GB switch entered in the system’s boot.ini file and takes effect after a restart.&lt;br /&gt;&lt;br /&gt;Which operating systems support the 3GB switch?&lt;br /&gt;The /3GB switch applies to 32-bit systems only. The following is a list of operating systems that support the 3GB switch:&lt;br /&gt;&lt;br /&gt;Windows Server 2003 Standard Edition&lt;br /&gt;Windows Server 2003 Enterprise Edition&lt;br /&gt;Windows Server 2003 Datacenter Edition&lt;br /&gt;Windows 2000 Advanced Server&lt;br /&gt;Windows 2000 Datacenter Server&lt;br /&gt;This is a list of officially supported operating systems that can handle the 3GB switch. Other systems may or may not handle it well depending on the hardware and software configuration.&lt;br /&gt;&lt;br /&gt;Can I use the /3GB switch on Windows XP?&lt;br /&gt;Adding the 3GB switch to the boot.ini file in Windows XP SP1 can cause Windows not to start.&lt;br /&gt;&lt;br /&gt;A supported fix is available from Microsoft, but it is only intended to correct the problem resulting from this specific setup. The solution to this problem is upgrade to the latest service pack. You can read more about this problem on the following Microsoft page:&lt;br /&gt;&lt;br /&gt;Windows XP SP1 May Not Start with the /3GB or /USERVA Switch&lt;br /&gt;http://support.microsoft.com/default.aspx?scid=kb;en-us;328269&lt;br /&gt;&lt;br /&gt;Can I use the /3GB switch on Windows Server 2000?&lt;br /&gt;The 3GB switch is officially supported on the 2000 Advanced Server. The official word is that it should not be used on Windows 2000 Server because it is unsupported and can cause application or operating system to crash.&lt;br /&gt;&lt;br /&gt;Important warning&lt;br /&gt;Any time you make a change to the boot.ini file, make sure that you have all your data backed up!&lt;br /&gt;&lt;br /&gt;Are there any other boot.ini parameters that I should know about?&lt;br /&gt;Yes, you might be interested in knowing about the /fastdetect switch: Fastdetect boot.ini switch.&lt;br /&gt;&lt;br /&gt;The Data Execution Prevention DEP setting can be also implemented in your BOOT.INI file through the NOEXECUTE switch. See the noexecute DEP parameter in boot.ini page for more details.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/15836190-5030613103482460922?l=forthosewhomatters.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://forthosewhomatters.blogspot.com/feeds/5030613103482460922/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=15836190&amp;postID=5030613103482460922' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/15836190/posts/default/5030613103482460922'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/15836190/posts/default/5030613103482460922'/><link rel='alternate' type='text/html' href='http://forthosewhomatters.blogspot.com/2009/09/3gb-switch-in-windows-bootini.html' title='3GB Switch in Windows boot.ini'/><author><name>For Those Who Matter</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-15836190.post-4333436711326108348</id><published>2009-09-10T08:19:00.001-07:00</published><updated>2009-09-10T08:19:47.499-07:00</updated><title type='text'>Is my xp 32bit or 64 bit?</title><content type='html'>Method 1&lt;br /&gt;1. Click Start, click Run, type sysdm.cpl, and then click OK.&lt;br /&gt;2. Click the General tab. The operating system appears as follows:&lt;br /&gt;(For a 64-bit version operating system: Microsoft Windows XP Professional x64 Edition Version &lt; Year&gt; appears under System. For a 32-bit version operating system: Microsoft Windows XP Professional Version&lt; Year&gt; appears under System.) Note &lt;Year&gt; is a placeholder for a year.&lt;br /&gt;&lt;br /&gt;Method 2&lt;br /&gt;1. Click Start, click Run, type winmsd.exe, and then click OK.&lt;br /&gt;2. In the details pane, locate Processor under Item. Note the value. (If the value that corresponds to Processor starts with x86, the computer is running a 32-bit version of the Windows operating system. If the value that corresponds to Processor starts with ia64 or AMD64, the computer is running a 64-bit version of the Windows operating system.)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/15836190-4333436711326108348?l=forthosewhomatters.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://forthosewhomatters.blogspot.com/feeds/4333436711326108348/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=15836190&amp;postID=4333436711326108348' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/15836190/posts/default/4333436711326108348'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/15836190/posts/default/4333436711326108348'/><link rel='alternate' type='text/html' href='http://forthosewhomatters.blogspot.com/2009/09/is-my-xp-32bit-or-64-bit.html' title='Is my xp 32bit or 64 bit?'/><author><name>For Those Who Matter</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-15836190.post-7560421262082023716</id><published>2009-09-10T07:22:00.000-07:00</published><updated>2009-09-10T07:33:44.207-07:00</updated><title type='text'>.Net, 64bit and 32 bit</title><content type='html'>Since .Net 2.0 was released, .Net started supporting 64bit programming.&lt;br /&gt;&lt;br /&gt;'CorFlags.exe' is a tool for you to peek the information inside a PE. It can be used to check whether an assembly is targetting 32bit or 64bit.&lt;br /&gt;&lt;br /&gt;Here's one sample query.&lt;br /&gt;&lt;br /&gt;D:\Project\BookingSheet\BookingSheetUI\bin\Release&gt;corflags bookingsheetui.exe&lt;br /&gt;&lt;br /&gt;Version   : v2.0.50727&lt;br /&gt;CLR Header: 2.5&lt;br /&gt;PE        : PE32&lt;br /&gt;CorFlags  : 3&lt;br /&gt;ILONLY    : 1&lt;br /&gt;32BIT     : 1&lt;br /&gt;Signed    : 0&lt;br /&gt;&lt;br /&gt;You can see that 32bit is set to 1 that means the exe is targetting 32bit.&lt;br /&gt;&lt;br /&gt;You can use "corflags bookingsheetui.exe \32bit+" to enforce the assembly to target 32bit. You can also use "corflags bookingsheetui.exe \32bit-" to enforce the assembly not use 32bit.&lt;br /&gt;&lt;br /&gt;An assembly that is targetting 32bit can also run at a 64bit WIN OS. It is called "WOW64".&lt;br /&gt;&lt;br /&gt;Migrating a managed program involved unmanaged codes is more complicated.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/15836190-7560421262082023716?l=forthosewhomatters.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://forthosewhomatters.blogspot.com/feeds/7560421262082023716/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=15836190&amp;postID=7560421262082023716' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/15836190/posts/default/7560421262082023716'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/15836190/posts/default/7560421262082023716'/><link rel='alternate' type='text/html' href='http://forthosewhomatters.blogspot.com/2009/09/net-64bit-and-32-bit.html' title='.Net, 64bit and 32 bit'/><author><name>For Those Who Matter</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-15836190.post-94384533611825028</id><published>2009-08-25T13:15:00.000-07:00</published><updated>2009-08-25T13:26:17.094-07:00</updated><title type='text'>Reactive Process Recycling</title><content type='html'>Reactive process recycling occurs when a process is misbehaving or unable to serve requests.&lt;br /&gt;&lt;br /&gt;Configuration settings that are related to this:&lt;br /&gt;&lt;br /&gt;requestQueueLimit: Handles deadlock conditions. The DWORD value is set to the maximum allowed number of requests in the queue, after which the worker process is considered to be misbehaving. When the number is exceeded, a new process is launched and the requests are reassigned. The default is 5000 requests. &lt;br /&gt;&lt;br /&gt;memoryLimit: Handles memory leak conditions. The DWORD value is set to the percentage of physical memory that the worker process can consume before it is considered to be misbehaving. When that percentage is exceeded, a new process is launched and the requests are reassigned. The default is 60%. &lt;br /&gt;&lt;br /&gt;shutdownTimeout: Specifies the amount of time the worker process has to shut itself down gracefully (string value in hr:min:sec format). When the time out expires, the ASP.NET ISAPI shuts down the worker process. The default is "00:00:05".&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/15836190-94384533611825028?l=forthosewhomatters.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://forthosewhomatters.blogspot.com/feeds/94384533611825028/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=15836190&amp;postID=94384533611825028' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/15836190/posts/default/94384533611825028'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/15836190/posts/default/94384533611825028'/><link rel='alternate' type='text/html' href='http://forthosewhomatters.blogspot.com/2009/08/reactive-process-recycling.html' title='Reactive Process Recycling'/><author><name>For Those Who Matter</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-15836190.post-4815081726379869141</id><published>2009-08-25T12:46:00.000-07:00</published><updated>2009-08-25T13:02:52.330-07:00</updated><title type='text'>Increase the memory limit</title><content type='html'>1) Booting the OS into /3GB mode &lt;br /&gt;2) Marking your assemblies as /LARGEADDRESSAWARE&lt;br /&gt;3) There may not be a contiguous block of memory large enough to satisfy your allocation.&lt;br /&gt;4) .NET imposes a 2GB object size limit, so trying to allocate an array larger than 2GB will fail.&lt;br /&gt;5) The exe that will be published is first created in the obj\release or obj\debug directory, depending on if this is a release or debug build.&lt;br /&gt;6) The postbuild is run before the .exe is copied to the bin\release\*.publish\publish version directory. &lt;br /&gt;7) Postbuild commands: $(ProjectDir)postbuild.bat $(ProjectDir)obj\$(ConfigurationName)\$(TargetFileName) $(TargetPath)&lt;br /&gt;8) Postbuild.bat file&lt;br /&gt;&lt;br /&gt;echo off&lt;br /&gt;&lt;br /&gt;call "%VS80COMNTOOLS%vsvars32.bat"&lt;br /&gt;&lt;br /&gt;editbin /largeaddressaware %1&lt;br /&gt;&lt;br /&gt;editbin /largeaddressaware %2&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/15836190-4815081726379869141?l=forthosewhomatters.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://forthosewhomatters.blogspot.com/feeds/4815081726379869141/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=15836190&amp;postID=4815081726379869141' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/15836190/posts/default/4815081726379869141'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/15836190/posts/default/4815081726379869141'/><link rel='alternate' type='text/html' href='http://forthosewhomatters.blogspot.com/2009/08/increase-memory-limit.html' title='Increase the memory limit'/><author><name>For Those Who Matter</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-15836190.post-1395172473278192149</id><published>2009-08-19T07:36:00.000-07:00</published><updated>2009-08-19T07:37:56.754-07:00</updated><title type='text'>An Introduction to OLAP in SQL Server 2005</title><content type='html'>http://www.devx.com/dbzone/Article/21410/0/page/3&lt;br /&gt;&lt;br /&gt;•Determine the required dimensions (bys) and measures (target data) .&lt;br /&gt;•Use Data Transformation Services to extract data from your source databases, transforming the data as needed, and loading the finished data into the cube.&lt;br /&gt;•Use the BI Workbench's Analysis Services wizards to build the measures, dimensions, and schema.&lt;br /&gt;•Provide cube browsers for your users so they can select and view reports. If necessary, write MDX queries or use automated tools, such as Excel Pivot Tables to query the cube.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/15836190-1395172473278192149?l=forthosewhomatters.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://forthosewhomatters.blogspot.com/feeds/1395172473278192149/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=15836190&amp;postID=1395172473278192149' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/15836190/posts/default/1395172473278192149'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/15836190/posts/default/1395172473278192149'/><link rel='alternate' type='text/html' href='http://forthosewhomatters.blogspot.com/2009/08/introduction-to-olap-in-sql-server-2005.html' title='An Introduction to OLAP in SQL Server 2005'/><author><name>For Those Who Matter</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-15836190.post-5200119305263178340</id><published>2009-07-15T13:42:00.000-07:00</published><updated>2009-07-16T07:50:19.399-07:00</updated><title type='text'>try/catch/finally</title><content type='html'>"try/catch/finally" is to handle unexpected exception so that the program will deterministic. But you have to be aware of that it only handle the codes that are in the block of "try".&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/15836190-5200119305263178340?l=forthosewhomatters.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://forthosewhomatters.blogspot.com/feeds/5200119305263178340/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=15836190&amp;postID=5200119305263178340' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/15836190/posts/default/5200119305263178340'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/15836190/posts/default/5200119305263178340'/><link rel='alternate' type='text/html' href='http://forthosewhomatters.blogspot.com/2009/07/trycatchfinally.html' title='try/catch/finally'/><author><name>For Those Who Matter</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-15836190.post-3682599427565048395</id><published>2009-07-06T07:37:00.000-07:00</published><updated>2009-07-06T08:00:17.246-07:00</updated><title type='text'>How ASP.NET Works with IIS</title><content type='html'>Svchost.exe is process that delivers Web publishing services (or in other words - iis). When an asp.net request comes, it will forward the request to asp.net working process - aspnet_wp.exe that is running under the account ASPNET.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/15836190-3682599427565048395?l=forthosewhomatters.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://forthosewhomatters.blogspot.com/feeds/3682599427565048395/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=15836190&amp;postID=3682599427565048395' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/15836190/posts/default/3682599427565048395'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/15836190/posts/default/3682599427565048395'/><link rel='alternate' type='text/html' href='http://forthosewhomatters.blogspot.com/2009/07/how-aspnet-works-with-iis.html' title='How ASP.NET Works with IIS'/><author><name>For Those Who Matter</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-15836190.post-53211760395083638</id><published>2009-07-06T07:04:00.000-07:00</published><updated>2009-07-06T07:20:15.240-07:00</updated><title type='text'>DB schema design - char, varchar, nchar, nvarchar and text</title><content type='html'>Database supplies mutilple field types to manage text data.&lt;br /&gt;&lt;br /&gt;If the length of the data in a field is relatively fixed, you should use char.&lt;br /&gt;&lt;br /&gt;If the length of the data varies, you should use varchar.&lt;br /&gt;&lt;br /&gt;If the data is unicode (16 bits characters), you should nchar or nvarchar.&lt;br /&gt;&lt;br /&gt;In old version, varchar and nvarchar can only hold chars no more than 8000 (?). In sql 2005 and future version, text, and ntext going to be replaced by varchar. (Image is replaced by varbinary(max)). Varchar(max) can hold 2(31) - 1 bytes or 2GB - 1 chars.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/15836190-53211760395083638?l=forthosewhomatters.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://forthosewhomatters.blogspot.com/feeds/53211760395083638/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=15836190&amp;postID=53211760395083638' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/15836190/posts/default/53211760395083638'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/15836190/posts/default/53211760395083638'/><link rel='alternate' type='text/html' href='http://forthosewhomatters.blogspot.com/2009/07/db-schema-design-char-varchar-nchar.html' title='DB schema design - char, varchar, nchar, nvarchar and text'/><author><name>For Those Who Matter</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-15836190.post-34239342863478970</id><published>2009-07-06T06:55:00.000-07:00</published><updated>2009-07-06T06:57:39.226-07:00</updated><title type='text'>ODBC and OLE</title><content type='html'>ODBC and OLE are both the utility for applications to connect to database. OLE is a native MS SQL server connector while ODBC is a general connector and can be used to connect to any Database that supports ODBC. &lt;br /&gt;&lt;br /&gt;For performance reason, if you know you are connecting to MS SQL database, you can choose to use OLE as your connector.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/15836190-34239342863478970?l=forthosewhomatters.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://forthosewhomatters.blogspot.com/feeds/34239342863478970/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=15836190&amp;postID=34239342863478970' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/15836190/posts/default/34239342863478970'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/15836190/posts/default/34239342863478970'/><link rel='alternate' type='text/html' href='http://forthosewhomatters.blogspot.com/2009/07/odbc-and-ole.html' title='ODBC and OLE'/><author><name>For Those Who Matter</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-15836190.post-8700893739698698277</id><published>2009-07-02T08:51:00.000-07:00</published><updated>2009-07-02T09:22:04.339-07:00</updated><title type='text'>WCF general</title><content type='html'>From service developer point of view, here's some main points.&lt;br /&gt;&lt;br /&gt;1)A service has to define a contract that is a interface. The contract defines the methods that are available for clients to use.&lt;br /&gt;&lt;br /&gt;2)The interface has to be implemented of course.&lt;br /&gt;&lt;br /&gt;3)In the service configuration file, you will define endpoint, binding and behaviors.&lt;br /&gt;&lt;br /&gt;4)An endpoint defines the address, contract and binding. A binding defines the protocols, securities and so on. A behavior may define whether exception details should be sent to the client side when the service is in debug mode.&lt;br /&gt;&lt;br /&gt;From a service client developer's point of view, the main points are:&lt;br /&gt;&lt;br /&gt;1)Generate or define a proxy of the service.&lt;br /&gt;&lt;br /&gt;2)Consume the service through the proxy.&lt;br /&gt;&lt;br /&gt;3)In the client configuration file, you will define client and bindings. The client will include the definition of an end point and the binding will define the protocols used for the service.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/15836190-8700893739698698277?l=forthosewhomatters.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://forthosewhomatters.blogspot.com/feeds/8700893739698698277/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=15836190&amp;postID=8700893739698698277' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/15836190/posts/default/8700893739698698277'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/15836190/posts/default/8700893739698698277'/><link rel='alternate' type='text/html' href='http://forthosewhomatters.blogspot.com/2009/07/wcf-general.html' title='WCF general'/><author><name>For Those Who Matter</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-15836190.post-4741007937474554579</id><published>2009-07-01T10:38:00.000-07:00</published><updated>2009-07-01T12:10:33.386-07:00</updated><title type='text'>WCF queue application</title><content type='html'>First, MSMQ (microsoft message queue) has to be installed on the developer's machine.&lt;br /&gt;If it is not there yet, it can be installed through "Control Panel". Choose add/remove programs and then choose add/remove windows component and check message queue.&lt;br /&gt;&lt;br /&gt;If the queue runs locally, it is usually private queue. &lt;br /&gt;&lt;br /&gt;Client side will still need a proxy. However, the codes have to be created manually since there's no contract between the client and the service. Each side interacts directly with the queue. The proxy still has the similar look as any other WCF's proxy.&lt;br /&gt;&lt;br /&gt;The client posts message to queue through the proxy.  The consumer side will dequeue the message and process it.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/15836190-4741007937474554579?l=forthosewhomatters.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://forthosewhomatters.blogspot.com/feeds/4741007937474554579/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=15836190&amp;postID=4741007937474554579' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/15836190/posts/default/4741007937474554579'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/15836190/posts/default/4741007937474554579'/><link rel='alternate' type='text/html' href='http://forthosewhomatters.blogspot.com/2009/07/wcf-queue-application.html' title='WCF queue application'/><author><name>For Those Who Matter</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-15836190.post-6934526782017213391</id><published>2009-06-29T13:53:00.000-07:00</published><updated>2009-06-29T13:59:22.416-07:00</updated><title type='text'>Creating a Partition View</title><content type='html'>A partition view combines data from multiple tables into one. Partition view can take advantage existed indexes on the combined tables and only query table partition that contains the data and thus improves the searching efficiency.&lt;br /&gt;&lt;br /&gt;To create a partition view, you just need add a CHECK constraint to the combined tables on a particular fields and therefore make sure there are no duplicate rows in the combined views.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/15836190-6934526782017213391?l=forthosewhomatters.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://forthosewhomatters.blogspot.com/feeds/6934526782017213391/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=15836190&amp;postID=6934526782017213391' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/15836190/posts/default/6934526782017213391'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/15836190/posts/default/6934526782017213391'/><link rel='alternate' type='text/html' href='http://forthosewhomatters.blogspot.com/2009/06/creating-partition-view.html' title='Creating a Partition View'/><author><name>For Those Who Matter</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-15836190.post-4234130942826171760</id><published>2009-06-29T12:56:00.000-07:00</published><updated>2009-06-29T13:19:15.107-07:00</updated><title type='text'>IPhone 3G (8g, 16g and 32g)</title><content type='html'>8G is only $99 that is $100 cheaper than 16g and $200 cheaper than 32g. However, the differences among the phones are not just the size of storage. 16G/32G has better camera and has video recording. They also have voice control and compass. 16G and 32G actually do no have much difference other than the storage size.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/15836190-4234130942826171760?l=forthosewhomatters.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://forthosewhomatters.blogspot.com/feeds/4234130942826171760/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=15836190&amp;postID=4234130942826171760' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/15836190/posts/default/4234130942826171760'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/15836190/posts/default/4234130942826171760'/><link rel='alternate' type='text/html' href='http://forthosewhomatters.blogspot.com/2009/06/iphone-3g-8g-16g-and-32g.html' title='IPhone 3G (8g, 16g and 32g)'/><author><name>For Those Who Matter</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-15836190.post-1813895918752789305</id><published>2009-03-21T11:12:00.000-07:00</published><updated>2009-03-21T11:22:08.007-07:00</updated><title type='text'>Questionnaire before buying a house</title><content type='html'>http://www.criteriumhomeinspection.com/100questions.pdf&lt;br /&gt;http://www.hud.gov/offices/hsg/sfh/buying/buyhm.cfm&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/15836190-1813895918752789305?l=forthosewhomatters.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://forthosewhomatters.blogspot.com/feeds/1813895918752789305/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=15836190&amp;postID=1813895918752789305' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/15836190/posts/default/1813895918752789305'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/15836190/posts/default/1813895918752789305'/><link rel='alternate' type='text/html' href='http://forthosewhomatters.blogspot.com/2009/03/questionnaire-before-buying-house.html' title='Questionnaire before buying a house'/><author><name>For Those Who Matter</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-15836190.post-5671972591559097667</id><published>2007-11-14T08:35:00.001-08:00</published><updated>2007-11-14T08:35:58.028-08:00</updated><title type='text'>Ten Common Database Design Mistakes</title><content type='html'>Ten Common Database Design Mistakes&lt;br /&gt;26 February 2007&lt;br /&gt;by Louis Davidson&lt;br /&gt;No list of mistakes is ever going to be exhaustive. People (myself included) do a lot of really stupid things, at times, in the name of "getting it done." This list simply reflects the database design mistakes that are currently on my mind, or in some cases, constantly on my mind.&lt;br /&gt;&lt;br /&gt;NOTE:&lt;br /&gt;I have done this topic two times before. If you're interested in hearing the podcast version, visit Greg Low's super-excellent SQL Down Under. I also presented a boiled down, ten-minute version at PASS for the Simple-Talk booth. Originally there were ten, then six, and today back to ten. And these aren't exactly the same ten that I started with; these are ten that stand out to me as of today.&lt;br /&gt;&lt;br /&gt;Before I start with the list, let me be honest for a minute. I used to have a preacher who made sure to tell us before some sermons that he was preaching to himself as much as he was to the congregation. When I speak, or when I write an article, I have to listen to that tiny little voice in my head that helps filter out my own bad habits, to make sure that I am teaching only the best practices. Hopefully, after reading this article, the little voice in your head will talk to you when you start to stray from what is right in terms of database design practices.&lt;br /&gt;&lt;br /&gt;So, the list:&lt;br /&gt;&lt;br /&gt;Poor design/planning &lt;br /&gt;Ignoring normalization &lt;br /&gt;Poor naming standards &lt;br /&gt;Lack of documentation &lt;br /&gt;One table to hold all domain values &lt;br /&gt;Using identity/guid columns as your only key &lt;br /&gt;Not using SQL facilities to protect data integrity &lt;br /&gt;Not using stored procedures to access data &lt;br /&gt;Trying to build generic objects&lt;br /&gt;Lack of testing&lt;br /&gt;Poor design/planning &lt;br /&gt;"If you don't know where you are going, any road will take you there" – George Harrison&lt;br /&gt;&lt;br /&gt;Prophetic words for all parts of life and a description of the type of issues that plague many projects these days.&lt;br /&gt;&lt;br /&gt;Let me ask you: would you hire a contractor to build a house and then demand that they start pouring a foundation the very next day? Even worse, would you demand that it be done without blueprints or house plans? Hopefully, you answered "no" to both of these. A design is needed make sure that the house you want gets built, and that the land you are building it on will not sink into some underground cavern. If you answered yes, I am not sure if anything I can say will help you.&lt;br /&gt;&lt;br /&gt;Like a house, a good database is built with forethought, and with proper care and attention given to the needs of the data that will inhabit it; it cannot be tossed together in some sort of reverse implosion.&lt;br /&gt;&lt;br /&gt;Since the database is the cornerstone of pretty much every business project, if you don't take the time to map out the needs of the project and how the database is going to meet them, then the chances are that the whole project will veer off course and lose direction. Furthermore, if you don't take the time at the start to get the database design right, then you'll find that any substantial changes in the database structures that you need to make further down the line could have a huge impact on the whole project, and greatly increase the likelihood of the project timeline slipping. &lt;br /&gt;&lt;br /&gt;Far too often, a proper planning phase is ignored in favor of just "getting it done". The project heads off in a certain direction and when problems inevitably arise – due to the lack of proper designing and planning – there is "no time" to go back and fix them properly, using proper techniques. That's when the "hacking" starts, with the veiled promise to go back and fix things later, something that happens very rarely indeed.&lt;br /&gt;&lt;br /&gt;Admittedly it is impossible to predict every need that your design will have to fulfill and every issue that is likely to arise, but it is important to mitigate against potential problems as much as possible, by careful planning.&lt;br /&gt;&lt;br /&gt;Ignoring Normalization &lt;br /&gt;Normalization defines a set of methods to break down tables to their constituent parts until each table represents one and only one "thing", and its columns serve to fully describe only the one "thing" that the table represents.&lt;br /&gt;&lt;br /&gt;The concept of normalization has been around for 30 years and is the basis on which SQL and relational databases are implemented. In other words, SQL was created to work with normalized data structures. Normalization is not just some plot by database programmers to annoy application programmers (that is merely a satisfying side effect!)&lt;br /&gt;&lt;br /&gt;SQL is very additive in nature in that, if you have bits and pieces of data, it is easy to build up a set of values or results. In the FROM clause, you take a set of data (a table) and add (JOIN) it to another table. You can add as many sets of data together as you like, to produce the final set you need. &lt;br /&gt;&lt;br /&gt;This additive nature is extremely important, not only for ease of development, but also for performance. Indexes are most effective when they can work with the entire key value. Whenever you have to use SUBSTRING, CHARINDEX, LIKE, and so on, to parse out a value that is combined with other values in a single column (for example, to split the last name of a person out of a full name column) the SQL paradigm starts to break down and data becomes become less and less searchable.&lt;br /&gt;&lt;br /&gt;So normalizing your data is essential to good performance, and ease of development, but the question always comes up: "How normalized is normalized enough?" If you have read any books about normalization, then you will have heard many times that 3rd Normal Form is essential, but 4th and 5th Normal Forms are really useful and, once you get a handle on them, quite easy to follow and well worth the time required to implement them.&lt;br /&gt;&lt;br /&gt;In reality, however, it is quite common that not even the first Normal Form is implemented correctly. &lt;br /&gt;&lt;br /&gt;Whenever I see a table with repeating column names appended with numbers, I cringe in horror. And I cringe in horror quite often. Consider the following example Customer table:&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Are there always 12 payments? Is the order of payments significant? Does a NULL value for a payment mean UNKNOWN (not filled in yet), or a missed payment? And when was the payment made?!?&lt;br /&gt;&lt;br /&gt;A payment does not describe a Customer and should not be stored in the Customer table. Details of payments should be stored in a Payment table, in which you could also record extra information about the payment, like when the payment was made, and what the payment was for:&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;In this second design, each column stores a single unit of information about a single "thing" (a payment), and each row represents a specific instance of a payment.&lt;br /&gt;&lt;br /&gt;This second design is going to require a bit more code early in the process but, it is far more likely that you will be able to figure out what is going on in the system without having to hunt down the original programmer and kick their butt…sorry… figure out what they were thinking &lt;br /&gt;&lt;br /&gt;Poor naming standards &lt;br /&gt;"That which we call a rose, by any other name would smell as sweet"&lt;br /&gt;&lt;br /&gt;This quote from Romeo and Juliet by William Shakespeare sounds nice, and it is true from one angle. If everyone agreed that, from now on, a rose was going to be called dung, then we could get over it and it would smell just as sweet. The problem is that if, when building a database for a florist, the designer calls it dung and the client calls it a rose, then you are going to have some meetings that sound far more like an Abbott and Costello routine than a serious conversation about storing information about horticulture products.&lt;br /&gt;&lt;br /&gt;Names, while a personal choice, are the first and most important line of documentation for your application. I will not get into all of the details of how best to name things here– it is a large and messy topic. What I want to stress in this article is the need for consistency. The names you choose are not just to enable you to identify the purpose of an object, but to allow all future programmers, users, and so on to quickly and easily understand how a component part of your database was intended to be used, and what data it stores. No future user of your design should need to wade through a 500 page document to determine the meaning of some wacky name.&lt;br /&gt;&lt;br /&gt;Consider, for example, a column named, X304_DSCR. What the heck does that mean? You might decide, after some head scratching, that it means "X304 description". Possibly it does, but maybe DSCR means discriminator, or discretizator?&lt;br /&gt;&lt;br /&gt;Unless you have established DSCR as a corporate standard abbreviation for description, then X304_DESCRIPTION is a much better name, and one leaves nothing to the imagination.&lt;br /&gt;&lt;br /&gt;That just leaves you to figure out what the X304 part of the name means. On first inspection, to me, X304 sounds like more like it should be data in a column rather than a column name. If I subsequently found that, in the organization, there was also an X305 and X306 then I would flag that as an issue with the database design. For maximum flexibility, data is stored in columns, not in column names.&lt;br /&gt;&lt;br /&gt;Along these same lines, resist the temptation to include "metadata" in an object's name. A name such as tblCustomer or colVarcharAddress might seem useful from a development perspective, but to the end user it is just confusing. As a developer, you should rely on being able to determine that a table name is a table name by context in the code or tool, and present to the users clear, simple, descriptive names, such as Customer and Address. &lt;br /&gt;&lt;br /&gt;A practice I strongly advise against is the use of spaces and quoted identifiers in object names. You should avoid column names such as "Part Number" or, in Microsoft style, [Part Number], therefore requiring you users to include these spaces and identifiers in their code. It is annoying and simply unnecessary.&lt;br /&gt;&lt;br /&gt;Acceptable alternatives would be part_number, partNumber or PartNumber. Again, consistency is key. If you choose PartNumber then that's fine – as long as the column containing invoice numbers is called InvoiceNumber, and not one of the other possible variations.&lt;br /&gt;&lt;br /&gt;Lack of documentation &lt;br /&gt;I hinted in the intro that, in some cases, I am writing for myself as much as you. This is the topic where that is most true. By carefully naming your objects, columns, and so on, you can make it clear to anyone what it is that your database is modeling. However, this is only step one in the documentation battle. The unfortunate reality is, though, that "step one" is all too often the only step.&lt;br /&gt;&lt;br /&gt;Not only will a well-designed data model adhere to a solid naming standard, it will also contain definitions on its tables, columns, relationships, and even default and check constraints, so that it is clear to everyone how they are intended to be used. In many cases, you may want to include sample values, where the need arose for the object, and anything else that you may want to know in a year or two when "future you" has to go back and make changes to the code. &lt;br /&gt;&lt;br /&gt;NOTE:&lt;br /&gt;Where this documentation is stored is largely a matter of corporate standards and/or convenience to the developer and end users. It could be stored in the database itself, using extended properties. Alternatively, it might be in maintained in the data modeling tools. It could even be in a separate data store, such as Excel or another relational database. My company maintains a metadata repository database, which we developed in order to present this data to end users in a searchable, linkable format. Format and usability is important, but the primary battle is to have the information available and up to date.&lt;br /&gt;&lt;br /&gt;Your goal should be to provide enough information that when you turn the database over to a support programmer, they can figure out your minor bugs and fix them (yes, we all make bugs in our code!). I know there is an old joke that poorly documented code is a synonym for "job security." While there is a hint of truth to this, it is also a way to be hated by your coworkers and never get a raise. And no good programmer I know of wants to go back and rework their own code years later. It is best if the bugs in the code can be managed by a junior support programmer while you create the next new thing. Job security along with raises is achieved by being the go-to person for new challenges.&lt;br /&gt;&lt;br /&gt;One table to hold all domain values &lt;br /&gt;"One Ring to rule them all and in the darkness bind them"&lt;br /&gt;&lt;br /&gt;This is all well and good for fantasy lore, but it's not so good when applied to database design, in the form of a "ruling" domain table. Relational databases are based on the fundamental idea that every object represents one and only one thing. There should never be any doubt as to what a piece of data refers to. By tracing through the relationships, from column name, to table name, to primary key, it should be easy to examine the relationships and know exactly what a piece of data means.&lt;br /&gt;&lt;br /&gt;The big myth perpetrated by architects who don't really understand relational database architecture (me included early in my career) is that the more tables there are, the more complex the design will be. So, conversely, shouldn't condensing multiple tables into a single "catch-all" table simplify the design? It does sound like a good idea, but at one time giving Pauly Shore the lead in a movie sounded like a good idea too.&lt;br /&gt;&lt;br /&gt;For example, consider the following model snippet where I needed domain values for:&lt;br /&gt;&lt;br /&gt;Customer CreditStatus &lt;br /&gt;Customer Type &lt;br /&gt;Invoice Status &lt;br /&gt;Invoice Line Item BackOrder Status &lt;br /&gt;Invoice Line Item Ship Via Carrier&lt;br /&gt;On the face of it that would be five domain tables…but why not just use one generic domain table, like this?&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;This may seem a very clean and natural way to design a table for all but the problem is that it is just not very natural to work with in SQL. Say we just want the domain values for the Customer table:&lt;br /&gt;&lt;br /&gt;SELECT *FROM Customer  JOIN GenericDomain as CustomerType    ON Customer.CustomerTypeId = CustomerType.GenericDomainId      and CustomerType.RelatedToTable = 'Customer'      and  CustomerType.RelatedToColumn = 'CustomerTypeId'  JOIN GenericDomain as CreditStatus    ON  Customer.CreditStatusId = CreditStatus.GenericDomainId      and CreditStatus.RelatedToTable = 'Customer'      and CreditStatus.RelatedToColumn = ' CreditStatusId'&lt;br /&gt;As you can see, this is far from being a natural join. It comes down to the problem of mixing apples with oranges. At first glance, domain tables are just an abstract concept of a container that holds text. And from an implementation centric standpoint, this is quite true, but it is not the correct way to build a database. In a database, the process of normalization, as a means of breaking down and isolating data, takes every table to the point where one row represents one thing. And each domain of values is a distinctly different thing from all of the other domains (unless it is not, in which case the one table will suffice.). So what you do, in essence, is normalize the data on each usage, spreading the work out over time, rather than doing the task once and getting it over with.&lt;br /&gt;&lt;br /&gt;So instead of the single table for all domains, you might model it as:&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Looks harder to do, right? Well, it is initially. Frankly it took me longer to flesh out the example tables. But, there are quite a few tremendous gains to be had:&lt;br /&gt;&lt;br /&gt;Using the data in a query is much easier:&lt;br /&gt;SELECT *FROM Customer  JOIN CustomerType    ON Customer.CustomerTypeId = CustomerType.CustomerTypeId  JOIN CreditStatus    ON  Customer.CreditStatusId = CreditStatus.CreditStatusId &lt;br /&gt;Data can be validated using foreign key constraints very naturally, something not feasible for the other solution unless you implement ranges of keys for every table – a terrible mess to maintain. &lt;br /&gt;If it turns out that you need to keep more information about a ShipViaCarrier than just the code, 'UPS', and description, 'United Parcel Service', then it is as simple as adding a column or two. You could even expand the table to be a full blown representation of the businesses that are carriers for the item. &lt;br /&gt;All of the smaller domain tables will fit on a single page of disk. This ensures a single read (and likely a single page in cache). If the other case, you might have your domain table spread across many pages, unless you cluster on the referring table name, which then could cause it to be more costly to use a non-clustered index if you have many values. &lt;br /&gt;You can still have one editor for all rows, as most domain tables will likely have the same base structure/usage. And while you would lose the ability to query all domain values in one query easily, why would you want to? (A union query could easily be created of the tables easily if needed, but this would seem an unlikely need.)&lt;br /&gt;I should probably rebut the thought that might be in your mind. "What if I need to add a new column to all domain tables?" For example, you forgot that the customer wants to be able to do custom sorting on domain values and didn't put anything in the tables to allow this. This is a fair question, especially if you have 1000 of these tables in a very large database. First, this rarely happens, and when it does it is going to be a major change to your database in either way.&lt;br /&gt;&lt;br /&gt;Second, even if this became a task that was required, SQL has a complete set of commands that you can use to add columns to tables, and using the system tables it is a pretty straightforward task to build a script to add the same column to hundreds of tables all at once. That will not be as easy of a change, but it will not be so much more difficult to outweigh the large benefits.&lt;br /&gt;&lt;br /&gt;The point of this tip is simply that it is better to do the work upfront, making structures solid and maintainable, rather than trying to attempt to do the least amount of work to start out a project. By keeping tables down to representing one "thing" it means that most changes will only affect one table, after which it follows that there will be less rework for you down the road.&lt;br /&gt;&lt;br /&gt;Using identity/guid columns as your only key &lt;br /&gt;First Normal Form dictates that all rows in a table must be uniquely identifiable. Hence, every table should have a primary key. SQL Server allows you to define a numeric column as an IDENTITY column, and then automatically generates a unique value for each row. Alternatively, you can use NEWID() (or NEWSEQUENTIALID()) to generate a random, 16 byte unique value for each row. These types of values, when used as keys, are what are known as surrogate keys. The word surrogate means "something that substitutes for" and in this case, a surrogate key should be the stand-in for a natural key. &lt;br /&gt;&lt;br /&gt;The problem is that too many designers use a surrogate key column as the only key column on a given table. The surrogate key values have no actual meaning in the real world; they are just there to uniquely identify each row.&lt;br /&gt;&lt;br /&gt;Now, consider the following Part table, whereby PartID is an IDENTITY column and is the primary key for the table:&lt;br /&gt;&lt;br /&gt;  PartID&lt;br /&gt; PartNumber&lt;br /&gt; Description&lt;br /&gt; &lt;br /&gt;1&lt;br /&gt; XXXXXXXX&lt;br /&gt; The X part&lt;br /&gt; &lt;br /&gt;2&lt;br /&gt; XXXXXXXX&lt;br /&gt; The X part&lt;br /&gt; &lt;br /&gt;3&lt;br /&gt; YYYYYYYY&lt;br /&gt; The Y part&lt;br /&gt; &lt;br /&gt;&lt;br /&gt;&lt;br /&gt;How many rows are there in this table? Well, there seem to be three, but are rows with PartIDs 1 and 2 actually the same row, duplicated? Or are they two different rows that should be unique but were keyed in incorrectly?&lt;br /&gt;&lt;br /&gt;The rule of thumb I use is simple. If a human being could not pick which row they want from a table without knowledge of the surrogate key, then you need to reconsider your design. This is why there should be a key of some sort on the table to guarantee uniqueness, in this case likely on PartNumber.&lt;br /&gt;&lt;br /&gt;In summary: as a rule, each of your tables should have a natural key that means something to the user, and can uniquely identify each row in your table. In the very rare event that you cannot find a natural key (perhaps, for example, a table that provides a log of events), then use an artificial/surrogate key.&lt;br /&gt;&lt;br /&gt;Not using SQL facilities to protect data integrity &lt;br /&gt;All fundamental, non-changing business rules should be implemented by the relational engine. The base rules of nullability, string length, assignment of foreign keys, and so on, should all be defined in the database. &lt;br /&gt;&lt;br /&gt;There are many different ways to import data into SQL Server. If your base rules are defined in the database itself can you guarantee that they will never be bypassed and you can write your queries without ever having to worry whether the data you're viewing adheres to the base business rules.&lt;br /&gt;&lt;br /&gt;Rules that are optional, on the other hand, are wonderful candidates to go into a business layer of the application. For example, consider a rule such as this: "For the first part of the month, no part can be sold at more than a 20% discount, without a manager's approval".&lt;br /&gt;&lt;br /&gt;Taken as a whole, this rule smacks of being rather messy, not very well controlled, and subject to frequent change. For example, what happens when next week the maximum discount is 30%? Or when the definition of "first part of the month" changes from 15 days to 20 days? Most likely you won't want go through the difficulty of implementing these complex temporal business rules in SQL Server code – the business layer is a great place to implement rules like this.&lt;br /&gt;&lt;br /&gt;However, consider the rule a little more closely. There are elements of it that will probably never change. E.g. &lt;br /&gt;&lt;br /&gt;The maximum discount it is ever possible to offer &lt;br /&gt;The fact that the approver must be a manager&lt;br /&gt;These aspects of the business rule very much ought to get enforced by the database and design. Even if the substance of the rule is implemented in the business layer, you are still going to have a table in the database that records the size of the discount, the date it was offered, the ID of the person who approved it, and so on. On the Discount column, you should have a CHECK constraint that restricts the values allowed in this column to between 0.00 and 0.90 (or whatever the maximum is). Not only will this implement your "maximum discount" rule, but will also guard against a user entering a 200% or a negative discount by mistake. On the ManagerID column, you should place a foreign key constraint, which reference the Managers table and ensures that the ID entered is that of a real manager (or, alternatively, a trigger that selects only EmployeeIds corresponding to managers).&lt;br /&gt;&lt;br /&gt;Now, at the very least we can be sure that the data meets the very basic rules that the data must follow, so we never have to code something like this in order to check that the data is good:&lt;br /&gt;&lt;br /&gt;SELECT CASE WHEN discount &lt; 0 then 0 else WHEN discount &gt; 1 then 1…&lt;br /&gt;We can feel safe that data meets the basic criteria, every time.&lt;br /&gt;&lt;br /&gt;Not using stored procedures to access data &lt;br /&gt;Stored procedures are your friend. Use them whenever possible as a method to insulate the database layer from the users of the data. Do they take a bit more effort? Sure, initially, but what good thing doesn't take a bit more time? Stored procedures make database development much cleaner, and encourage collaborative development between your database and functional programmers. A few of the other interesting reasons that stored procedures are important include the following.&lt;br /&gt;&lt;br /&gt;Maintainability&lt;br /&gt;Stored procedures provide a known interface to the data, and to me, this is probably the largest draw. When code that accesses the database is compiled into a different layer, performance tweaks cannot be made without a functional programmer's involvement. Stored procedures give the database professional the power to change characteristics of the database code without additional resource involvement, making small changes, or large upgrades (for example changes to SQL syntax) easier to do. &lt;br /&gt;&lt;br /&gt;Encapsulation&lt;br /&gt;Stored procedures allow you to "encapsulate" any structural changes that you need to make to the database so that the knock on effect on user interfaces is minimized. For example, say you originally modeled one phone number, but now want an unlimited number of phone numbers. You could leave the single phone number in the procedure call, but store it in a different table as a stopgap measure, or even permanently if you have a "primary" number of some sort that you always want to display. Then a stored proc could be built to handle the other phone numbers. In this manner the impact to the user interfaces could be quite small, while the code of stored procedures might change greatly. &lt;br /&gt;&lt;br /&gt;Security&lt;br /&gt;Stored procedures can provide specific and granular access to the system. For example, you may have 10 stored procedures that all update table X in some way. If a user needs to be able to update a particular column in a table and you want to make sure they never update any others, then you can simply grant to that user the permission to execute just the one procedure out of the ten that allows them perform the required update. &lt;br /&gt;&lt;br /&gt;Performance&lt;br /&gt;There are a couple of reasons that I believe stored procedures enhance performance. First, if a newbie writes ratty code (like using a cursor to go row by row through an entire ten million row table to find one value, instead of using a WHERE clause), the procedure can be rewritten without impact to the system (other than giving back valuable resources.) The second reason is plan reuse. Unless you are using dynamic SQL calls in your procedure, SQL Server can store a plan and not need to compile it every time it is executed. It's true that in every version of SQL Server since 7.0 this has become less and less significant, as SQL Server gets better at storing plans ad hoc SQL calls (see note below). However, stored procedures still make it easier for plan reuse and performance tweaks. In the case where ad hoc SQL would actually be faster, this can be coded into the stored procedure seamlessly.&lt;br /&gt;&lt;br /&gt;In 2005, there is a database setting (PARAMETERIZATION FORCED) that, when enabled, will cause all queries to have their plans saved. This does not cover more complicated situations that procedures would cover, but can be a big help. There is also a feature known as plan guides, which allow you to override the plan for a known query type. Both of these features are there to help out when stored procedures are not used, but stored procedures do the job with no tricks.&lt;br /&gt;&lt;br /&gt;And this list could go on and on. There are drawbacks too, because nothing is ever perfect. It can take longer to code stored procedures than it does to just use ad hoc calls. However, the amount of time to design your interface and implement it is well worth it, when all is said and done.&lt;br /&gt;&lt;br /&gt;Trying to code generic T-SQL objects &lt;br /&gt;I touched on this subject earlier in the discussion of generic domain tables, but the problem is more prevalent than that. Every new T-SQL programmer, when they first start coding stored procedures, starts to think "I wish I could just pass a table name as a parameter to a procedure." It does sound quite attractive: one generic stored procedure that can perform its operations on any table you choose. However, this should be avoided as it can be very detrimental to performance and will actually make life more difficult in the long run.&lt;br /&gt;&lt;br /&gt;T-SQL objects do not do "generic" easily, largely because lots of design considerations in SQL Server have clearly been made to facilitate reuse of plans, not code. SQL Server works best when you minimize the unknowns so it can produce the best plan possible. The more it has to generalize the plan, the less it can optimize that plan. &lt;br /&gt;&lt;br /&gt;Note that I am not specifically talking about dynamic SQL procedures. Dynamic SQL is a great tool to use when you have procedures that are not optimizable / manageable otherwise. A good example is a search procedure with many different choices. A precompiled solution with multiple OR conditions might have to take a worst case scenario approach to the plan and yield weak results, especially if parameter usage is sporadic. &lt;br /&gt;&lt;br /&gt;However, the main point of this tip is that you should avoid coding very generic objects, such as ones that take a table name and twenty column names/value pairs as a parameter and lets you update the values in the table. For example, you could write a procedure that started out:&lt;br /&gt;&lt;br /&gt;CREATE PROCEDURE updateAnyTable@tableName sysname,@columnName1 sysname,@columnName1Value varchar(max)@columnName2 sysname,@columnName2Value varchar(max)…&lt;br /&gt;The idea would be to dynamically specify the name of a column and the value to pass to a SQL statement. This solution is no better than simply using ad hoc calls with an UPDATE statement. Instead, when building stored procedures, you should build specific, dedicated stored procedures for each task performed on a table (or multiple tables.) This gives you several benefits:&lt;br /&gt;&lt;br /&gt;Properly compiled stored procedures can have a single compiled plan attached to it and reused. &lt;br /&gt;Properly compiled stored procedures are more secure than ad-hoc SQL or even dynamic SQL procedures, reducing the surface area for an injection attack greatly because the only parameters to queries are search arguments or output values. &lt;br /&gt;Testing and maintenance of compiled stored procedures is far easier to do since you generally have only to search arguments, not that tables/columns/etc exist and handling the case where they do not&lt;br /&gt;A nice technique is to build a code generation tool in your favorite programming language (even T-SQL) using SQL metadata to build very specific stored procedures for every table in your system. Generate all of the boring, straightforward objects, including all of the tedious code to perform error handling that is so essential, but painful to write more than once or twice.&lt;br /&gt;&lt;br /&gt;In my Apress book, Pro SQL Server 2005 Database Design and Optimization, I provide several such "templates" (manly for triggers, abut also stored procedures) that have all of the error handling built in, I would suggest you consider building your own (possibly based on mine) to use when you need to manually build a trigger/procedure or whatever.&lt;br /&gt;&lt;br /&gt;Lack of testing &lt;br /&gt;When the dial in your car says that your engine is overheating, what is the first thing you blame? The engine. Why don't you immediately assume that the dial is broken? Or something else minor? Two reasons:&lt;br /&gt;&lt;br /&gt;The engine is the most important component of the car and it is common to blame the most important part of the system first. &lt;br /&gt;It is all too often true.&lt;br /&gt;As database professionals know, the first thing to get blamed when a business system is running slow is the database. Why? First because it is the central piece of most any business system, and second because it also is all too often true.&lt;br /&gt;&lt;br /&gt;We can play our part in dispelling this notion, by gaining deep knowledge of the system we have created and understanding its limits through testing.&lt;br /&gt;&lt;br /&gt;But let's face it; testing is the first thing to go in a project plan when time slips a bit. And what suffers the most from the lack of testing? Functionality? Maybe a little, but users will notice and complain if the "Save" button doesn't actually work and they cannot save changes to a row they spent 10 minutes editing. What really gets the shaft in this whole process is deep system testing to make sure that the design you (presumably) worked so hard on at the beginning of the project is actually implemented correctly. &lt;br /&gt;&lt;br /&gt;But, you say, the users accepted the system as working, so isn't that good enough? The problem with this statement is that what user acceptance "testing" usually amounts to is the users poking around, trying out the functionality that they understand and giving you the thumbs up if their little bit of the system works. Is this reasonable testing? Not in any other industry would this be vaguely acceptable. Do you want your automobile tested like this? "Well, we drove it slowly around the block once, one sunny afternoon with no problems; it is good!" When that car subsequently "failed" on the first drive along a freeway, or during the first drive through rain or snow, then the driver would have every right to be very upset.&lt;br /&gt;&lt;br /&gt;Too many database systems get tested like that car, with just a bit of poking around to see if individual queries and modules work. The first real test is in production, when users attempt to do real work. This is especially true when it is implemented for a single client (even worse when it is a corporate project, with management pushing for completion more than quality). &lt;br /&gt;&lt;br /&gt;Initially, major bugs come in thick and fast, especially performance related ones. If the first time you have tried a full production set of users, background process, workflow processes, system maintenance routines, ETL, etc, is on your system launch day, you are extremely likely to discover that you have not anticipated all of the locking issues that might be caused by users creating data while others are reading it, or hardware issues cause by poorly set up hardware. It can take weeks to live down the cries of "SQL Server can't handle it" even after you have done the proper tuning.&lt;br /&gt;&lt;br /&gt;Once the major bugs are squashed, the fringe cases (which are pretty rare cases, like a user entering a negative amount for hours worked) start to raise their ugly heads. What you end up with at this point is software that irregularly fails in what seem like weird places (since large quantities of fringe bugs will show up in ways that aren't very obvious and are really hard to find.) &lt;br /&gt;&lt;br /&gt;Now, it is far harder to diagnose and correct because now you have to deal with the fact that users are working with live data and trying to get work done. Plus you probably have a manager or two sitting on your back saying things like "when will it be done?" every 30 seconds, even though it can take days and weeks to discover the kinds of bugs that result in minor (yet important) data aberrations. Had proper testing been done, it would never have taken weeks of testing to find these bugs, because a proper test plan takes into consideration all possible types of failures, codes them into an automated test, and tries them over and over. Good testing won't find all of the bugs, but it will get you to the point where most of the issues that correspond to the original design are ironed out.&lt;br /&gt;&lt;br /&gt;If everyone insisted on a strict testing plan as an integral and immutable part of the database development process, then maybe someday the database won't be the first thing to be fingered when there is a system slowdown.&lt;br /&gt;&lt;br /&gt;Summary &lt;br /&gt;Database design and implementation is the cornerstone of any data centric project (read 99.9% of business applications) and should be treated as such when you are developing. This article, while probably a bit preachy, is as much a reminder to me as it is to anyone else who reads it. Some of the tips, like planning properly, using proper normalization, using a strong naming standards and documenting your work– these are things that even the best DBAs and data architects have to fight to make happen. In the heat of battle, when your manager's manager's manager is being berated for things taking too long to get started, it is not easy to push back and remind them that they pay you now, or they pay you later. These tasks pay dividends that are very difficult to quantify, because to quantify success you must fail first. And even when you succeed in one area, all too often other minor failures crop up in other parts of the project so that some of your successes don't even get noticed.&lt;br /&gt;&lt;br /&gt;The tips covered here are ones that I have picked up over the years that have turned me from being mediocre to a good data architect/database programmer. None of them take extraordinary amounts of time (except perhaps design and planning) but they all take more time upfront than doing it the "easy way". Let's face it, if the easy way were that easy in the long run, I for one would abandon the harder way in a second. It is not until you see the end result that you realize that success comes from starting off right as much as finishing right.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/15836190-5671972591559097667?l=forthosewhomatters.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://forthosewhomatters.blogspot.com/feeds/5671972591559097667/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=15836190&amp;postID=5671972591559097667' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/15836190/posts/default/5671972591559097667'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/15836190/posts/default/5671972591559097667'/><link rel='alternate' type='text/html' href='http://forthosewhomatters.blogspot.com/2007/11/ten-common-database-design-mistakes.html' title='Ten Common Database Design Mistakes'/><author><name>For Those Who Matter</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-15836190.post-535381589717522946</id><published>2007-11-14T08:34:00.001-08:00</published><updated>2007-11-14T08:34:33.575-08:00</updated><title type='text'>WaitHandles - Auto/ManualResetEvent and Mutex</title><content type='html'>Monitor.Wait/Pulse isn't the only way of waiting for something to happen in one thread and telling that thread that it's happened in another. Win32 programmers have been using various other mechanisms for a long time, and these are exposed by the AutoResetEvent, ManualResetEvent and Mutex classes, all of which derive from WaitHandle. All of these classes are in the System.Threading namespace. (The Win32 Semaphore mechanism does not have a managed wrapper in .NET 1.1. It's present in .NET 2.0, but if you need to use it before then, you could either wrap it yourself using P/Invoke, or write your own counting semaphore class.) &lt;br /&gt;&lt;br /&gt;Some people may be surprised to learn that using these classes can be significantly slower than using the various Monitor methods. I believe this is because going "out" of managed code into native Win32 calls and back "in" again is expensive compared with the entirely managed view of things which Monitor provides. A reader has also explained that monitors are implemented in user mode, whereas using wait handles require switching into kernel mode, which is fairly expensive. &lt;br /&gt;&lt;br /&gt;WaitHandle itself only exposes a few useful instance methods/properties: &lt;br /&gt;&lt;br /&gt;WaitOne() - used to wait for the handle to be free/signalled. The exact meaning of this depends on the concrete type being used (Mutex, AutoResetEvent or ManualResetEvent). &lt;br /&gt;Close()/Dispose() - used to release the resources used by the handle. &lt;br /&gt;Handle - used to get the native handle being wrapped. Most developers won't need to use this. &lt;br /&gt;In addition, it has two useful static methods which deal with sets of WaitHandles: &lt;br /&gt;&lt;br /&gt;WaitAny() - used to wait for any of the handles in a set to be free/signalled. &lt;br /&gt;WaitAll() - used to wait for all of the handles in a set to be free/signalled. &lt;br /&gt;All of the WaitXXX() methods have overloads allowing you to specify a timeout and whether or not to exit the "synchronization domain". The default value is false. What is a synchronization domain, you ask? Well, it's to do with some automatic thread handling that .NET has to offer in the guise of Transactional COM+. Most .NET developers won't need to use this, but Juval Löwy has an article on the topic if you wish to find out more. &lt;br /&gt;&lt;br /&gt;Auto/ManualResetEvent&lt;br /&gt;The two "event" classes (which are entirely different from .NET events - don't get the two confused) come as a sort of pair, and are very similar. You can think of them like doors - when they're in the "signalled" (or "set") state they're open, and when they're in the "non-signalled" (or "reset") state, they're closed. A call to WaitOne() waits for the door to be opened so the thread can "go through it" in some sense. The difference between the two classes is that an AutoResetEvent will reset itself to the non-signalled state immediately after a call to WaitOne() - it's as if anyone going through the door closes it behind them. With a ManualResetEvent, you have to tell the thread to reset it (close the door) when you want to make calls to WaitOne() block again. Both classes can manually be set or reset at any time, by any thread, using the Set and Reset methods, and can be created in the signalled/set or non-signalled/reset state. (These methods return a boolean value saying whether or not they were successful, but the documentation doesn't state why they might fail.) &lt;br /&gt;&lt;br /&gt;Here's some sample code which simulates 10 runners. Each runner is passed a ManualResetEvent which is initially non-signalled. When the runner completes the race, it signals the event. The main thread uses WaitHandle.WaitAny to wait for the first runner to finish, and uses the value returned by the method to say who won the race. It then uses WaitHandle.WaitAll to wait for everyone to finish. Note that if we'd used AutoResetEvent instead, we'd have to call Set on the event of the winner, as it would have been reset when we detected it being set with the call to WaitAny. &lt;br /&gt;&lt;br /&gt;    &lt;br /&gt;using System;&lt;br /&gt;using System.Threading;&lt;br /&gt;&lt;br /&gt;class Test&lt;br /&gt;{&lt;br /&gt;    static void Main()&lt;br /&gt;    {&lt;br /&gt;        ManualResetEvent[] events = new ManualResetEvent[10];&lt;br /&gt;        for (int i=0; i &lt; events.Length; i++)&lt;br /&gt;        {&lt;br /&gt;            events[i] = new ManualResetEvent(false);&lt;br /&gt;            Runner r = new Runner(events[i], i);&lt;br /&gt;            new Thread(new ThreadStart(r.Run)).Start();&lt;br /&gt;        }&lt;br /&gt;        &lt;br /&gt;        int index = WaitHandle.WaitAny(events);&lt;br /&gt;        &lt;br /&gt;        Console.WriteLine ("***** The winner is {0} *****", &lt;br /&gt;                           index);&lt;br /&gt;        &lt;br /&gt;        WaitHandle.WaitAll(events);&lt;br /&gt;        Console.WriteLine ("All finished!");&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;class Runner&lt;br /&gt;{&lt;br /&gt;    static readonly object rngLock = new object();&lt;br /&gt;    static Random rng = new Random();&lt;br /&gt;    &lt;br /&gt;    ManualResetEvent ev;&lt;br /&gt;    int id;&lt;br /&gt;    &lt;br /&gt;    internal Runner (ManualResetEvent ev, int id)&lt;br /&gt;    {&lt;br /&gt;        this.ev = ev;&lt;br /&gt;        this.id = id;&lt;br /&gt;    }&lt;br /&gt;    &lt;br /&gt;    internal void Run()&lt;br /&gt;    {&lt;br /&gt;        for (int i=0; i &lt; 10; i++)&lt;br /&gt;        {&lt;br /&gt;            int sleepTime;&lt;br /&gt;            // Not sure about the thread safety of Random...&lt;br /&gt;            lock (rngLock)&lt;br /&gt;            {&lt;br /&gt;                sleepTime = rng.Next(2000);&lt;br /&gt;            }&lt;br /&gt;            Thread.Sleep(sleepTime);&lt;br /&gt;            Console.WriteLine ("Runner {0} at stage {1}",&lt;br /&gt;                               id, i);&lt;br /&gt;        }&lt;br /&gt;        ev.Set();&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt; &lt;br /&gt;&lt;br /&gt;Mutex&lt;br /&gt;Whereas Auto/ManualResetEvent have a lot in common with using Monitor.Wait/Pulse, Mutex has even more in common with Monitor.Enter/Exit. A mutex has a count of the number of times it's been acquired, and a thread which is the current owner. If the count is zero, it has no owner and it can be acquired by anyone. If the count is non-zero, the current owner can acquire it however many times they like without blocking, but any other thread has to wait until the count becomes zero before they can acquire it. The WaitXXX() methods are used to acquire the mutex, and ReleaseMutex() is used by the owner thread to decrease the count by one. Only the owner can decrease the count. &lt;br /&gt;&lt;br /&gt;So far, so much like Monitor. The difference is that a Mutex is a cross-process object - the same mutex can be used in many processes, if you give it a name. A thread in one process can wait for a thread in another process to release the mutex, etc. When you construct a named mutex, you should be careful about making assumptions as to whether or not you will be able to acquire initial ownership of it. Fortunately, there is a constructor which allows the code to detect whether the system has created a whole new mutex or whether it's used an existing one. If the constructor requested initial ownership, it will only have been granted it if it created a new mutex - even if the existing mutex can immediately be acquired. &lt;br /&gt;&lt;br /&gt;Mutex names should start with either "Local\" or "Global\" to indicate whether they should be created in the local or global namespace respectively. (I believe that local is the default, but why take the risk? Make it explicit in the name.) If you create a mutex in the global namespace, it is shared with other users logged into the same machine. If you create a mutex in the local namespace, it is specific to the current user. Make sure you pick a suitably unique name so you don't clash with other programs. &lt;br /&gt;&lt;br /&gt;To be honest, I think the principle use that mutexes will be put to in .NET is the one mentioned earlier - detecting that another instance of an application is already running. Most people don't need inter-process communication on this kind of level. The other use is to enable you to block until either one or all of a set of WaitHandles is released. For other purposes, where Monitor is good enough, I suggest using that - especially as C# has the lock statement specifically to support it. Here's an example of detecting a running application, however: &lt;br /&gt;&lt;br /&gt;using System;&lt;br /&gt;using System.Threading;&lt;br /&gt;&lt;br /&gt;class Test&lt;br /&gt;{&lt;br /&gt;    static void Main()&lt;br /&gt;    {&lt;br /&gt;        bool firstInstance;&lt;br /&gt;        &lt;br /&gt;        using (Mutex mutex = new Mutex(true, &lt;br /&gt;                                       @"Global\Jon.Skeet.MutexTestApp",&lt;br /&gt;                                       out firstInstance))&lt;br /&gt;        {&lt;br /&gt;            if (!firstInstance)&lt;br /&gt;            {&lt;br /&gt;                Console.WriteLine ("Other instance detected; aborting.");&lt;br /&gt;                return;&lt;br /&gt;            }&lt;br /&gt;            &lt;br /&gt;            Console.WriteLine ("We're the only instance running - yay!");&lt;br /&gt;            for (int i=0; i &lt; 10; i++)&lt;br /&gt;            {&lt;br /&gt;                Console.WriteLine (i);&lt;br /&gt;                Thread.Sleep(1000);&lt;br /&gt;            }&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt; &lt;br /&gt;&lt;br /&gt;Run the example in two different console windows - one will count to ten slowly; the other will abort after it detects that the other application instance is running. Note the using statement around the mutex: this should extend across the whole of the application's execution, otherwise another instance would be able to create a new mutex with the same name, after the old one had been destroyed. For instance, suppose you use a local variable without a using statement, like this: &lt;br /&gt;&lt;br /&gt;using System;&lt;br /&gt;using System.Threading;&lt;br /&gt;&lt;br /&gt;class Test&lt;br /&gt;{&lt;br /&gt;    static void Main()&lt;br /&gt;    {&lt;br /&gt;        bool firstInstance;&lt;br /&gt;        &lt;br /&gt;        // Bad code - do not use!&lt;br /&gt;        Mutex mutex = new Mutex(true, &lt;br /&gt;                                @"Global\Jon.Skeet.MutexTestApp",&lt;br /&gt;                                out firstInstance);&lt;br /&gt;        &lt;br /&gt;        if (!firstInstance)&lt;br /&gt;        {&lt;br /&gt;            Console.WriteLine ("Other instance detected; aborting.");&lt;br /&gt;            return;&lt;br /&gt;        }&lt;br /&gt;        &lt;br /&gt;        Console.WriteLine ("We're the only instance running - yay!");&lt;br /&gt;        for (int i=0; i &lt; 10; i++)&lt;br /&gt;        {&lt;br /&gt;            Console.WriteLine (i);&lt;br /&gt;            Thread.Sleep(1000);&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt; &lt;br /&gt;&lt;br /&gt;In that case, you'd probably find that everything would work fine under debug, where the GC is very conservative about what it collects. When not running under the debugger, however, the GC can tell that the mutex variable isn't used after its initial assignment, so for the main duration of the app, it can be garbage collected at any time - and that destroys the mutex! The using statement shown earlier is only one way round this. You could make it a static variable instead, or use GC.KeepAlive(mutex); at the end of the method to make sure that the GC doesn't ignore the variable.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/15836190-535381589717522946?l=forthosewhomatters.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://forthosewhomatters.blogspot.com/feeds/535381589717522946/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=15836190&amp;postID=535381589717522946' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/15836190/posts/default/535381589717522946'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/15836190/posts/default/535381589717522946'/><link rel='alternate' type='text/html' href='http://forthosewhomatters.blogspot.com/2007/11/waithandles-automanualresetevent-and.html' title='WaitHandles - Auto/ManualResetEvent and Mutex'/><author><name>For Those Who Matter</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-15836190.post-8506725237988040239</id><published>2007-11-14T08:33:00.001-08:00</published><updated>2007-11-14T08:33:33.243-08:00</updated><title type='text'>Working with Windows Service Using Visual Studio 2005</title><content type='html'>http://aspalliance.com/1316_Working_with_Windows_Service_Using_Visual_Studio_2005#Page2&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/15836190-8506725237988040239?l=forthosewhomatters.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://forthosewhomatters.blogspot.com/feeds/8506725237988040239/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=15836190&amp;postID=8506725237988040239' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/15836190/posts/default/8506725237988040239'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/15836190/posts/default/8506725237988040239'/><link rel='alternate' type='text/html' href='http://forthosewhomatters.blogspot.com/2007/11/working-with-windows-service-using.html' title='Working with Windows Service Using Visual Studio 2005'/><author><name>For Those Who Matter</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-15836190.post-116775608645127745</id><published>2007-01-02T08:40:00.001-08:00</published><updated>2007-01-02T08:41:26.453-08:00</updated><title type='text'>Calling __doPostBack in javascript</title><content type='html'>Update: There is an existing .Net Framework method Page.GetPostBackEventReference that emits client-side script that initiates postback and also provides a reference to the control that initiated the postback event. It is well described in MSDN article “Generating Client-Side Script for Postback“. So my function should call &lt;br /&gt;&lt;br /&gt;ctrl.Page.GetPostBackEventReference(ctrl) instead of &lt;br /&gt;__doPostBack('" + UniqueIDWithDollars(ctrl) + @"',''); &lt;br /&gt;&lt;br /&gt;and in most cases GetPostBackEventReference can be used directly.&lt;br /&gt;&lt;br /&gt;Original Post: &lt;br /&gt;&lt;br /&gt;I've used a function to submit postback from my javascript by passing Id of the link server control as it was suggested in article “How postback works in ASP.NET” &lt;br /&gt;&lt;br /&gt;//call the postback function with the right ID &lt;br /&gt;__doPostBack('ControlId',''); &lt;br /&gt;and it worked fine for a while.&lt;br /&gt;&lt;br /&gt;However when I moved the link to the User control, it stopped to work.&lt;br /&gt;&lt;br /&gt;I recognized that I need to provide fully qualified Control.ClientId but it didn't work.&lt;br /&gt;In debugger I found that when calling the __doPostBack(), ASP.NET generates ID with dollar - $ -separator, not underscore that is used in ClientID, e.g. 'userContol1$linkContol1'. &lt;br /&gt;&lt;br /&gt;I found confirmation to this in ASP.NET Server Control - Design Time Support and .NET Development: PressButton Design and Server Control . Microsoft provides UniqueIDWithDollars internal method, that can be accessed through reflection.&lt;br /&gt;&lt;br /&gt;However I found that it is simpler just to duplicate code in static function.&lt;br /&gt;&lt;br /&gt;The working version of javascript function to __doPostBack :&lt;br /&gt;&lt;br /&gt;public static bool RegisterFunctionToPostBack(string sFunctionName,Control ctrl)&lt;br /&gt;&lt;br /&gt;{ //from http://www.xefteri.com/articles/show.cfm?id=18 How postback works in ASP.NET&lt;br /&gt;&lt;br /&gt;if (HttpContext.Current.Request.Browser.JavaScript)&lt;br /&gt;&lt;br /&gt;{&lt;br /&gt;string sJS =" function " + sFunctionName + @"()&lt;br /&gt;&lt;br /&gt;{&lt;br /&gt;&lt;br /&gt;//call the postback function with the right ID&lt;br /&gt;&lt;br /&gt;__doPostBack('" + UniqueIDWithDollars(ctrl) + @"','');&lt;br /&gt;&lt;br /&gt;}";&lt;br /&gt;&lt;br /&gt;sJS=JScriptHelper.JScript(sJS);&lt;br /&gt;&lt;br /&gt;ctrl.Page.RegisterStartupScript(sFunctionName, sJS);&lt;br /&gt;&lt;br /&gt;return true;&lt;br /&gt;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;return false;&lt;br /&gt;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;//from http://www.codeproject.com/aspnet/DesignTimeSupport.asp &lt;br /&gt;&lt;br /&gt;public static string UniqueIDWithDollars(Control ctrl)&lt;br /&gt;&lt;br /&gt;{&lt;br /&gt;&lt;br /&gt;string sId = ctrl.UniqueID;&lt;br /&gt;&lt;br /&gt;if (sId == null)&lt;br /&gt;&lt;br /&gt;{&lt;br /&gt;&lt;br /&gt;return null;&lt;br /&gt;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;if (sId.IndexOf(':') &gt;= 0)&lt;br /&gt;&lt;br /&gt;{&lt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/15836190-116775608645127745?l=forthosewhomatters.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://forthosewhomatters.blogspot.com/feeds/116775608645127745/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=15836190&amp;postID=116775608645127745' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/15836190/posts/default/116775608645127745'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/15836190/posts/default/116775608645127745'/><link rel='alternate' type='text/html' href='http://forthosewhomatters.blogspot.com/2007/01/calling-dopostback-in-javascript.html' title='Calling __doPostBack in javascript'/><author><name>For Those Who Matter</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-15836190.post-116775601720820365</id><published>2007-01-02T08:40:00.000-08:00</published><updated>2007-01-02T08:40:17.213-08:00</updated><title type='text'>Garbage collection &amp; weak references</title><content type='html'>I have been reading parts of Inside C# (Vol 2) today. Specifically I've focused on the chapters concerning garbage collection and related subjects. Just reading those parts, I have to say that this book does a pretty good job of outlining some of the details that happen behind the scene. It describes how garbage collection is implemented in the framework and provides some examples to go along with it. Anyway, the part that I found interesting (I had heard about this briefly before) was how the runtime assigns objects on the heap to a generation. Currently with .Net 1.x, there are 3 generations that an object can be a part of. When garbage collection occurs, it “sweeps” the first generation (0), releasing the memory associated with those objects. If there isn’t enough memory available for the current operation, the garbage collector will sweep the next generation (1). It continues doing this until enough memory has been released to fulfill the current requirement. Granted, the garbage collector uses an algorithm to determine which objects to collect, etc… If an object survives a “sweep” operation, it’s generation is incremented. But the cool part to all of this is that newer objects are added to the lowest generation (0). So what this means is that typically, objects more local in scope are collected before/will have a shorter lifetime than objects of a less local scope. &lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Also, I was reading about weak references a little bit. I stumbled upon weak references when I was working with NAnt a while back. I never really found a resource to describe what the point of weak references is. This has all changed, thanks to this book :) So basically, you use weak references when you are using objects that are costly to instantiate/setup. Say you have your large object that the user has access to; the user switches to a different part of your application where the object isn’t needed. You can create a weak reference to that object and then proceed to dispose/destroy the strong reference to the object. If the user switches back to the original part of the application where that object would be used again, it’s possible to get back the strong reference by using the weak reference. Thus, you avoid the cost of setting up the object. Wow, that was a confusing sentence. The way that I think this all works is that you tell the runtime that you no longer need the object, making it available for garbage collection. A weak reference is like a pointer, pointing to where the object exists in memory. If later on, that object has not been collected, you can re-create the strong reference to it. The week reference class has a property called IsAlive to test if the object exists still or not. That’s my take on it, if I’m wrong please inform me...&lt;br /&gt;&lt;br /&gt;The below is a sample usage.&lt;br /&gt;&lt;br /&gt;...&lt;br /&gt;WeakReference wa = null;&lt;br /&gt;try&lt;br /&gt;{&lt;br /&gt;A a = new A();&lt;br /&gt;wa = new WeakReference(a, false);&lt;br /&gt;}&lt;br /&gt;ca&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/15836190-116775601720820365?l=forthosewhomatters.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://forthosewhomatters.blogspot.com/feeds/116775601720820365/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=15836190&amp;postID=116775601720820365' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/15836190/posts/default/116775601720820365'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/15836190/posts/default/116775601720820365'/><link rel='alternate' type='text/html' href='http://forthosewhomatters.blogspot.com/2007/01/garbage-collection-weak-references.html' title='Garbage collection &amp; weak references'/><author><name>For Those Who Matter</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-15836190.post-116775598555989833</id><published>2007-01-02T08:39:00.000-08:00</published><updated>2007-01-02T08:39:45.560-08:00</updated><title type='text'>Post a data file directly to your client</title><content type='html'>Response.Clear();&lt;br /&gt;System.IO.FileInfo oFileInfo = new System.IO.FileInfo(sFilePath);&lt;br /&gt;Response.AddHeader("Content-Disposition", "attachment; filename=" + oFileInfo.Name);&lt;br /&gt;Response.ContentType = sMimeType;&lt;br /&gt;DocumentQry oQry = new DocumentQry() ;&lt;br /&gt;using(new iDeal.Common.Utilities.SafeDisposer(oQry))&lt;br /&gt;{&lt;br /&gt;byte[] bFile = oQry.GetFile(sFilePath) ;&lt;br /&gt;Response.BinaryWrite(bFile) ;&lt;br /&gt;}&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/15836190-116775598555989833?l=forthosewhomatters.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://forthosewhomatters.blogspot.com/feeds/116775598555989833/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=15836190&amp;postID=116775598555989833' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/15836190/posts/default/116775598555989833'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/15836190/posts/default/116775598555989833'/><link rel='alternate' type='text/html' href='http://forthosewhomatters.blogspot.com/2007/01/post-data-file-directly-to-your-client.html' title='Post a data file directly to your client'/><author><name>For Those Who Matter</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-15836190.post-116775589768964351</id><published>2007-01-02T08:38:00.000-08:00</published><updated>2007-01-02T08:38:17.690-08:00</updated><title type='text'>Query Active Directory using VB script</title><content type='html'>'Global variables&lt;br /&gt;Dim sCustomer&lt;br /&gt;Dim sDomain&lt;br /&gt;Dim oContainer&lt;br /&gt;Dim OutPutFile&lt;br /&gt;Dim FileSystem&lt;br /&gt;'Initialize global variables&lt;br /&gt;sCustomer = "Lehman Brothers"&lt;br /&gt;sDomain = "DC=ideal,DC=qa,DC=local"&lt;br /&gt;Set FileSystem = WScript.CreateObject("Scripting.FileSystemObject")&lt;br /&gt;Set OutPutFile = FileSystem.CreateTextFile("cellphone.txt", True) &lt;br /&gt;Set oContainer=GetObject("LDAP://OU=" &amp; sCustomer &amp; ",OU=Customers,OU=Phoenix Application," &amp; sDomain)&lt;br /&gt;'Enumerate Container&lt;br /&gt;EnumerateUsers oContainer&lt;br /&gt;'Clean up&lt;br /&gt;OutPutFile.Close&lt;br /&gt;Set FileSystem = Nothing&lt;br /&gt;Set oContainer = Nothing&lt;br /&gt;WScript.Echo "Finished"&lt;br /&gt;WScript.Quit(0)&lt;br /&gt;Sub EnumerateUsers(oCont)&lt;br /&gt;Dim oUserInfo&lt;br /&gt;For Each oUserInfo In oCont&lt;br /&gt;Select Case LCase(oUserInfo.Class)&lt;br /&gt;Case "user"&lt;br /&gt;If (Not IsEmpty(oUserInfo.UserPrincipalName) and Not IsEmpty(oUserInfo.mobile)) Then&lt;br /&gt;OutPutFile.WriteLine oUserInfo.UserPrincipalName &amp; " ^ " &amp; oUserInfo.mobile&lt;br /&gt;End If&lt;br /&gt;Case "organizationalunit"&lt;br /&gt;EnumerateUsers oUserInfo&lt;br /&gt;End Select&lt;br /&gt;Next&lt;br /&gt;End Sub&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/15836190-116775589768964351?l=forthosewhomatters.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://forthosewhomatters.blogspot.com/feeds/116775589768964351/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=15836190&amp;postID=116775589768964351' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/15836190/posts/default/116775589768964351'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/15836190/posts/default/116775589768964351'/><link rel='alternate' type='text/html' href='http://forthosewhomatters.blogspot.com/2007/01/query-active-directory-using-vb-script.html' title='Query Active Directory using VB script'/><author><name>For Those Who Matter</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-15836190.post-116775586207941517</id><published>2007-01-02T08:37:00.000-08:00</published><updated>2007-01-02T08:37:42.080-08:00</updated><title type='text'>So which CLR will my app use</title><content type='html'>So which CLR will my app use?&lt;br /&gt;&lt;br /&gt;We have shipped several versions of .Net framework: 1.0, 1.1, and 2.0 is on the horizon. All of them are side by side, meaning, someone may be using 1.0 CLR, at the same time, someone else is using 1.1 CLR. In the same process, there can be only one CLR. Once CLR is loaded in the process, it cannot be unloaded.&lt;br /&gt;&lt;br /&gt;So which CLR will my app use?&lt;br /&gt;&lt;br /&gt;It depends on which .Net framework has installed, and which framework your app is built with.&lt;br /&gt;&lt;br /&gt;The real component to determine which CLR to load is mscoree.dll, residing in %windir%\system32. When you install .Net framework, it will replace mscoree.dll if the existing one is older then the one it carries, and it will leave it alone if the existing one is newer. So we always have the latest mscoree.dll in %windir%\system32, even the corresponding .Net framework has been uninstalled. For this reason, mscoree.dll has to maintain very strict compatibility. &lt;br /&gt;&lt;br /&gt;Because we always have the latest mscoree.dll, the following discussion is based on what newest .Net framework you have ever installed.&lt;br /&gt;&lt;br /&gt;If only 1.0 is installed, then 1.0 CLR will always be used. 1.0 mscoree.dll is not side by side aware.&lt;br /&gt;&lt;br /&gt;If 1.1 is installed, then the CLR you built with will be loaded. If you built your app with 1.0, then 1.0 CLR will be loaded. If you built your app with 1.1, then 1.1 CLR will be loaded. If the required CLR is not available in your machine, mscoree.dll will bring up a dialog and quit. This is so that your app won’t run under a different CLR that you did not test.&lt;br /&gt;&lt;br /&gt;The thinking shifts in 2.0. In 2.0, mscoree.dll will try to use the CLR you built with first. If that CLR cannot be found, mscoree.dll will load 2.0 CLR to run your app. But if the CLR you built with is newer than (the currently installed) 2.0, mscoree.dll will bring up the same dialog and quit. The latter behavior is frequently seen in internal testing. &lt;br /&gt;&lt;br /&gt;For apps built with interim release, mscoree.dll maps it to the closest officially released CLR. So 1.0 beta2+ will use 1.0 CLR. 1.1 beta will use 1.1 CLR.&lt;br /&gt;&lt;br /&gt;Of course, you can use a config file to overwrite the default behavior. &lt;br /&gt;&lt;br /&gt;http://msdn.microsoft.com/library/en-us/cpguide/html/cpconside-by-sideexecution.asp has more information.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/15836190-116775586207941517?l=forthosewhomatters.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://forthosewhomatters.blogspot.com/feeds/116775586207941517/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=15836190&amp;postID=116775586207941517' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/15836190/posts/default/116775586207941517'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/15836190/posts/default/116775586207941517'/><link rel='alternate' type='text/html' href='http://forthosewhomatters.blogspot.com/2007/01/so-which-clr-will-my-app-use.html' title='So which CLR will my app use'/><author><name>For Those Who Matter</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-15836190.post-116775576819377275</id><published>2007-01-02T08:35:00.001-08:00</published><updated>2007-01-02T08:36:08.196-08:00</updated><title type='text'>The CLR's execution engine</title><content type='html'>The CLR's execution engine&lt;br /&gt;&lt;br /&gt;Let's start by taking a look at the basics of the CLR when it comes to executing code. The central file in this story is mscoree.dll (Component Object Runtime Execution Engine), which contains the execution engine. Well, that's not completely true actually. Mscoree is called the "startup shim" and is unique on the machine, regardless of the number of side-by-side installations of the .NET Framework (e.g. 1.0.3705, 1.1.4322, 2.0.x). You'll find the file in the system32 folder on your system. It's the task of the mscoree.dll file to hand over execution to a specific version of the CLR depending on a number of factors. Such an installation of a version of the CLR contains a bunch of files starting with mscor, such as:&lt;br /&gt;&lt;br /&gt;mscorwks.dll - the workstation version of the CLR &lt;br /&gt;mscorsvr.dll - the server version of the CLR (I'll talk about the workstation and server versions in a later post when talking about the garbage collector etc) &lt;br /&gt;mscorlib.dll - contains a part of the System namespace of managed classes (e.g. System.Activator is in there, whileas System.Uri lives in the System.dll assembly); this file contains low-level functionality that has a close relationship with the CLR itself (e.g. code to support concepts such as application domains) &lt;br /&gt;mscorjit.dll - the just-in-time compiler of the CLR to compile IL-code to native code at runtime&lt;br /&gt;You can find all these files in the Microsoft.NET\Framework folders in your Windows directory. As you can have multiple different versions of the CLR on one machine, it's the job of the startup shim (which is not installed on a version-per-version basis) to load a specific version of the CLR and to hand over execution to that particular version.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/15836190-116775576819377275?l=forthosewhomatters.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://forthosewhomatters.blogspot.com/feeds/116775576819377275/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=15836190&amp;postID=116775576819377275' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/15836190/posts/default/116775576819377275'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/15836190/posts/default/116775576819377275'/><link rel='alternate' type='text/html' href='http://forthosewhomatters.blogspot.com/2007/01/clrs-execution-engine.html' title='The CLR&apos;s execution engine'/><author><name>For Those Who Matter</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-15836190.post-116775573050786763</id><published>2007-01-02T08:35:00.000-08:00</published><updated>2007-01-02T08:35:30.520-08:00</updated><title type='text'>NotesSQL 3.02j ODBC error 126 when adding DSN</title><content type='html'>When trying to add a DSN via the MS ODBC Data Source Administrator I get the following errors:&lt;br /&gt;&lt;br /&gt;"The setup routines for the Lotus NotesSQL Driver (*.nsf) ODBC driver could not be loaded due to system error code 126."&lt;br /&gt;&lt;br /&gt;"Driver's ConfigDSN, Config Driver, or ConfigTranslator failed&lt;br /&gt;Could not load the setup or translator library"&lt;br /&gt;&lt;br /&gt;The Solution is:&lt;br /&gt;&lt;br /&gt;make sure your enviornment path has both: C:\Lotus\Notes or C:\NotesSQL.&lt;br /&gt;&lt;br /&gt;Or if you install NotesSql in other path, you need make sure those paths are inccluded in environmental path.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/15836190-116775573050786763?l=forthosewhomatters.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://forthosewhomatters.blogspot.com/feeds/116775573050786763/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=15836190&amp;postID=116775573050786763' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/15836190/posts/default/116775573050786763'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/15836190/posts/default/116775573050786763'/><link rel='alternate' type='text/html' href='http://forthosewhomatters.blogspot.com/2007/01/notessql-302j-odbc-error-126-when.html' title='NotesSQL 3.02j ODBC error 126 when adding DSN'/><author><name>For Those Who Matter</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-15836190.post-116775538570237650</id><published>2007-01-02T08:29:00.000-08:00</published><updated>2007-01-02T08:29:45.703-08:00</updated><title type='text'>Disable address bar in Internet Explorer 7</title><content type='html'>Problem - How to disable address bar in Internet Explorer &lt;br /&gt;Environment – Internet Explorer 7 &lt;br /&gt;&lt;br /&gt;I searched our existing case database and found a similar case. Following are the summary of key points discussed in that case: &lt;br /&gt;1. Address bar behaviour: &lt;br /&gt;(a) the enabled address bar will show up in all user-initiated IE7 windows, as you cannot customize the user-initiated IE7 by disabling the enabled address bar. &lt;br /&gt;&lt;br /&gt;(b) the enabled address bar will always show up in IE7 for script-opened window if window.open command does not specify anything. &lt;br /&gt;&lt;br /&gt;(c) The disabled address bar will show up in a script-opened window even if window.open suppresses it under default internet-zone setting (i.e., “allow websites to open windows without address or status bar” is defaulted to ‘disabled’). &lt;br /&gt;&lt;br /&gt;2. The address bar can be suppressed under the following circumstances: &lt;br /&gt;(a) Via script-opened window (i.e., via window.open) provided if we use “toolbar=no” (we can just use this alone without specifying others) &lt;br /&gt;&lt;br /&gt;(b) If we use “location=no” (without specifying the “fullscreen” flag together), and under the circumstance that IE7 setting “allow websites to open windows without address or status bar” is set to ‘enabled’. &lt;br /&gt;&lt;br /&gt;PS: The latter setting is defaulted to ‘enabled’ under “intranet zone” or “trusted site” category. &lt;br /&gt;&lt;br /&gt;3. The reason to force showing the address bar, under defaulted internet zone setting, is to alert end users about un-trusted location of website so users know when they have been redirected to a different website. This is by-design and is a given security implementation of Microsoft. The only ways out, as mentioned earlier, are at end-user’s discretion, to enable the “allow open windows without address bar…” flag in IE7 settings for script-opened windows or to add the website domain in to trusted zone.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/15836190-116775538570237650?l=forthosewhomatters.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://forthosewhomatters.blogspot.com/feeds/116775538570237650/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=15836190&amp;postID=116775538570237650' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/15836190/posts/default/116775538570237650'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/15836190/posts/default/116775538570237650'/><link rel='alternate' type='text/html' href='http://forthosewhomatters.blogspot.com/2007/01/disable-address-bar-in-internet.html' title='Disable address bar in Internet Explorer 7'/><author><name>For Those Who Matter</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-15836190.post-114539543034240533</id><published>2006-04-18T14:13:00.000-07:00</published><updated>2006-04-18T14:23:50.620-07:00</updated><title type='text'>Interface vs Abstract Class</title><content type='html'>Class vs. interface &lt;br /&gt;Some say you should define all classes in terms of interfaces, but I think recommendation seems a bit extreme. I use interfaces when I see that something in my design will change frequently. &lt;br /&gt;&lt;br /&gt;For example, the Strategy pattern lets you swap new algorithms and processes into your program without altering the objects that use them. A media player might know how to play CDs, MP3s, and wav files. Of course, you don't want to hardcode those playback algorithms into the player; that will make it difficult to add a new format like AVI. Furthermore, your code will be littered with useless case statements. And to add insult to injury, you will need to update those case statements each time you add a new algorithm. All in all, this is not a very object-oriented way to program. &lt;br /&gt;&lt;br /&gt;With the Strategy pattern, you can simply encapsulate the algorithm behind an object. If you do that, you can provide new media plug-ins at any time. Let's call the plug-in class MediaStrategy. That object would have one method: playStream(Stream s). So to add a new algorithm, we simply extend our algorithm class. Now, when the program encounters the new media type, it simply delegates the playing of the stream to our media strategy. Of course, you'll need some plumbing to properly instantiate the algorithm strategies you will need. &lt;br /&gt;&lt;br /&gt;This is an excellent place to use an interface. We've used the Strategy pattern, which clearly indicates a place in the design that will change. Thus, you should define the strategy as an interface. You should generally favor interfaces over inheritance when you want an object to have a certain type; in this case, MediaStrategy. Relying on inheritance for type identity is dangerous; it locks you into a particular inheritance hierarchy. Java doesn't allow multiple inheritance, so you can't extend something that gives you a useful implementation or more type identity. &lt;br /&gt;&lt;br /&gt;Interface vs. abstract class &lt;br /&gt;Choosing interfaces and abstract classes is not an either/or proposition. If you need to change your design, make it an interface. However, you may have abstract classes that provide some default behavior. Abstract classes are excellent candidates inside of application frameworks. &lt;br /&gt;&lt;br /&gt;Abstract classes let you define some behaviors; they force your subclasses to provide others. For example, if you have an application framework, an abstract class may provide default services such as event and message handling. Those services allow your application to plug in to your application framework. However, there is some application-specific functionality that only your application can perform. Such functionality might include startup and shutdown tasks, which are often application-dependent. So instead of trying to define that behavior itself, the abstract base class can declare abstract shutdown and startup methods. The base class knows that it needs those methods, but an abstract class lets your class admit that it doesn't know how to perform those actions; it only knows that it must initiate the actions. When it is time to start up, the abstract class can call the startup method. When the base class calls this method, Java calls the method defined by the child class. &lt;br /&gt;&lt;br /&gt;Many developers forget that a class that defines an abstract method can call that method as well. Abstract classes are an excellent way to create planned inheritance hierarchies. They're also a good choice for nonleaf classes in class hierarchies.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/15836190-114539543034240533?l=forthosewhomatters.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://forthosewhomatters.blogspot.com/feeds/114539543034240533/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=15836190&amp;postID=114539543034240533' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/15836190/posts/default/114539543034240533'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/15836190/posts/default/114539543034240533'/><link rel='alternate' type='text/html' href='http://forthosewhomatters.blogspot.com/2006/04/interface-vs-abstract-class.html' title='Interface vs Abstract Class'/><author><name>For Those Who Matter</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-15836190.post-114142369160525482</id><published>2006-03-03T14:03:00.000-08:00</published><updated>2006-03-03T14:20:53.690-08:00</updated><title type='text'>ASP.NET - encrype your password with salt</title><content type='html'>MD5CryptoServiceProvider md5Hasher = New MD5CryptoServiceProvider()&lt;br /&gt;    &lt;br /&gt;Byte[] hashedBytes = new Byte[];   &lt;br /&gt;UTF8Encoding encoder = New UTF8Encoding();&lt;br /&gt;&lt;br /&gt;use&lt;br /&gt;&lt;br /&gt;hashedBytes = md5Hasher.ComputeHash(encoder.GetBytes(txtPwd.Text &amp; txtUsername.Text))&lt;br /&gt;&lt;br /&gt;instead of&lt;br /&gt;&lt;br /&gt;hashedBytes = md5Hasher.ComputeHash(encoder.GetBytes(txtPwd.Text))&lt;br /&gt;&lt;br /&gt;Note: The Password field is of type binary and of length 16.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/15836190-114142369160525482?l=forthosewhomatters.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://forthosewhomatters.blogspot.com/feeds/114142369160525482/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=15836190&amp;postID=114142369160525482' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/15836190/posts/default/114142369160525482'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/15836190/posts/default/114142369160525482'/><link rel='alternate' type='text/html' href='http://forthosewhomatters.blogspot.com/2006/03/aspnet-encrype-your-password-with-salt.html' title='ASP.NET - encrype your password with salt'/><author><name>For Those Who Matter</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-15836190.post-113988971782968774</id><published>2006-02-13T20:01:00.000-08:00</published><updated>2006-02-13T20:45:30.693-08:00</updated><title type='text'>Technical Interview Questions</title><content type='html'>The following is a list of questions which have been floating around some &lt;br /&gt;Internet circles. They are excellent prep questions for a technical interview.&lt;br /&gt;&lt;br /&gt;I haven't made any attempt to clean them up, spelling or organization wise. &lt;br /&gt;&lt;br /&gt;Don't bother asking me for the answers, &lt;br /&gt; 1) I don't have an answer key. &lt;br /&gt; 2) It'd do you good to think.&lt;br /&gt;&lt;br /&gt;  1. Given a rectangular (cuboidal for the puritans) cake with a rectangular&lt;br /&gt;     piece removed (any size or orientation), how would you cut the remainder&lt;br /&gt;     of the cake into two equal halves with one straight cut of a knife ?&lt;br /&gt; &lt;br /&gt;  2. You're given an array containing both positive and negative integers and&lt;br /&gt;     required to find the subarray with the largest sum (O(N) a la KBL).&lt;br /&gt;     Write a routine in C for the above.&lt;br /&gt; &lt;br /&gt;  3. Given an array of size N in which every number is between 1 and N,&lt;br /&gt;     determine if there are any duplicates in it.  You are allowed to destroy&lt;br /&gt;     the array if you like. [ I ended up giving about 4 or 5 different solutions&lt;br /&gt;     for this, each supposedly better than the others ].&lt;br /&gt; &lt;br /&gt;  4. Write a routine to draw a circle (x ** 2 + y ** 2 = r ** 2) without making&lt;br /&gt;     use of any floating point computations at all.  [ This one had me stuck for&lt;br /&gt;     quite some time and I first gave a solution that did have floating point&lt;br /&gt;     computations ].&lt;br /&gt; &lt;br /&gt;  5. Given only putchar (no sprintf, itoa, etc.) write a routine putlong that&lt;br /&gt;     prints out an unsigned long in decimal.  [ I gave the obvious solution of&lt;br /&gt;     taking % 10 and / 10, which gives us the decimal value in reverse order.&lt;br /&gt;     This requires an array since we need to print it out in the correct order.&lt;br /&gt;     The interviewer wasn't too pleased and asked me to give a solution which&lt;br /&gt;     didn't need the array ].&lt;br /&gt;&lt;br /&gt;void print(unsigned n)&lt;br /&gt;{&lt;br /&gt;        static c = 0;&lt;br /&gt; if( n &lt;  10) &lt;br /&gt; {&lt;br /&gt;   putchar(n + 48);&lt;br /&gt;          return;&lt;br /&gt; }&lt;br /&gt; int m = n%10;&lt;br /&gt;        print(n/10);&lt;br /&gt; if(++c%3 == 0) putchar(',');&lt;br /&gt; putchar(48 + m);&lt;br /&gt;}&lt;br /&gt; &lt;br /&gt;  6. Give a one-line C expression to test whether a number is a power of&lt;br /&gt;     2. [No loops allowed - it's a simple test.]&lt;br /&gt; &lt;br /&gt;  7. Given an array of characters which form a sentence of words, give an&lt;br /&gt;     efficient algorithm to reverse the order of the words (not characters)&lt;br /&gt;     in it.&lt;br /&gt; &lt;br /&gt;  8. How many points are there on the globe where by walking one mile south,&lt;br /&gt;     one mile east and one mile north you reach the place where you started.&lt;br /&gt; &lt;br /&gt;  9. Give a very good method to count the number of ones in a 32 bit number.&lt;br /&gt;     (caution: looping through testing each bit is not a solution).&lt;br /&gt; &lt;br /&gt; 10. What are the different ways to say, the value of x can be either a 0&lt;br /&gt;     or a 1. Apparently the if then else solution has a jump when written&lt;br /&gt;     out in assembly.&lt;br /&gt;        if (x == 0)&lt;br /&gt;                y=0&lt;br /&gt;        else&lt;br /&gt;                y =x&lt;br /&gt;&lt;br /&gt;        There is a logical, arithmetic and a datastructure soln to the above&lt;br /&gt;        problem.&lt;br /&gt;&lt;br /&gt; 11. Reverse a linked list.&lt;br /&gt;&lt;br /&gt; 12. Insert in a sorted list&lt;br /&gt;&lt;br /&gt; 13. In a X's and 0's game (i.e. TIC TAC TOE) if you write a program for&lt;br /&gt;     this give a gast way to generate the moves by the computer. I mean this&lt;br /&gt;     should be the fasteset way possible. The answer is that you need to store&lt;br /&gt;     all possible configurations of the board and the move that is associated&lt;br /&gt;     with that. Then it boils down to just accessing the right element and&lt;br /&gt;     getting the corresponding move for it. Do some analysis and do some more&lt;br /&gt;     optimization in storage since otherwise it becomes infeasible to get&lt;br /&gt;     the required storage in a DOS machine.&lt;br /&gt;&lt;br /&gt; 14. I was given two lines of assembly code which found the absolute value&lt;br /&gt;     of a number stored in two's complement form. I had to recognize what the&lt;br /&gt;     code was doing. Pretty simple if you know some assembly and some fundaes&lt;br /&gt;     on number representation.&lt;br /&gt;&lt;br /&gt; 15. Give a fast way to multiply a number by 7.&lt;br /&gt;&lt;br /&gt; 16. How would go about finding out where to find a book in a library. (You&lt;br /&gt;     don't know how exactly the books are organized beforehand).&lt;br /&gt;&lt;br /&gt; 17. Linked list manipulation.&lt;br /&gt;&lt;br /&gt; 18. Tradeoff between time spent in testing a product and getting into the&lt;br /&gt;     market first.&lt;br /&gt;&lt;br /&gt; 19. What to test for given that there isn't enough time to test everything&lt;br /&gt;     you want to.&lt;br /&gt;&lt;br /&gt; 20. First some definitions for this problem:&lt;br /&gt;    a) An ASCII character is one byte long and the most significant bit&lt;br /&gt;       in the byte is always '0'.&lt;br /&gt;    b) A Kanji character is two bytes long. The only characteristic of a&lt;br /&gt;       Kanji character is that in its first byte the most significant bit&lt;br /&gt;       is '1'.&lt;br /&gt;&lt;br /&gt;     Now you are given an array of a characters (both ASCII and Kanji) and,&lt;br /&gt;     an index into the array. The index points to the start of some character.&lt;br /&gt;     Now you need to write a function to do a backspace (i.e. delete the&lt;br /&gt;     character before the given index).&lt;br /&gt;&lt;br /&gt; 21. Delete an element from a doubly linked list.&lt;br /&gt;&lt;br /&gt; 22. Write a function to find the depth of a binary tree.&lt;br /&gt;&lt;br /&gt; 23. Given two strings S1 and S2. Delete from S2 all those characters which&lt;br /&gt;     occur in S1 also and finally create a clean S2 with the relevant characters&lt;br /&gt;     deleted.&lt;br /&gt;&lt;br /&gt; 24. Assuming that locks are the only reason due to which deadlocks can occur&lt;br /&gt;     in a system. What would be a foolproof method of avoiding deadlocks in&lt;br /&gt;     the system.&lt;br /&gt;&lt;br /&gt; 25. Reverse a linked list.&lt;br /&gt;&lt;br /&gt; 26. Write a small lexical analyzer - interviewer gave tokens. expressions like&lt;br /&gt;     "a*b" etc.&lt;br /&gt;&lt;br /&gt; 27. Besides communication cost, what is the other source of inefficiency in RPC?&lt;br /&gt;&lt;br /&gt;     (answer : context switches, excessive buffer copying).&lt;br /&gt;     How can you optimise the communication? (ans : communicate through shared&lt;br /&gt;     memory on same machine, bypassing the kernel _ A Univ. of Wash. thesis)&lt;br /&gt;&lt;br /&gt; 28. Write a routine that prints out a 2-D array in spiral order!&lt;br /&gt;&lt;br /&gt; 29. How is the readers-writers problem solved? - using semaphores/ada .. etc.&lt;br /&gt;&lt;br /&gt; 30. Ways of optimizing symbol table storage in compilers.&lt;br /&gt;&lt;br /&gt; 31. A walk-through through the symbol table functions, lookup() implementation&lt;br /&gt;     etc - The interv. was on the Microsoft C team.&lt;br /&gt;&lt;br /&gt; 32. A version of the "There are three persons X Y Z, one of which always lies"..&lt;br /&gt;&lt;br /&gt;     etc..&lt;br /&gt;&lt;br /&gt; 33. There are 3 ants at 3 corners of a triangle, they randomly start moving&lt;br /&gt;     towards another corner.. what is the probability that they don't collide.&lt;br /&gt;&lt;br /&gt; 34. Write an efficient algo and C code to shuffle a pack of cards.. this one&lt;br /&gt;     was a feedback process until we came up with one with no extra storage.&lt;br /&gt;&lt;br /&gt; 35. The if (x == 0) y  = 0 etc..&lt;br /&gt;&lt;br /&gt; 36. Some more bitwise optimization at assembly level&lt;br /&gt;&lt;br /&gt; 37. Some general questions on Lex Yacc etc.&lt;br /&gt;&lt;br /&gt; 38. Given an array t[100] which contains numbers between 1..99.&lt;br /&gt;     Return the duplicated value. Try both O(n) and O(n-square).&lt;br /&gt;&lt;br /&gt; 39. Given an array of characters. How would you reverse it. ?&lt;br /&gt;     How would you reverse it without using indexing in the array.&lt;br /&gt;&lt;br /&gt; 40. GIven a sequence of characters. How will you convert the lower&lt;br /&gt;     case characters to upper case characters. ( Try using bit vector&lt;br /&gt;     - sol given in the C  lib -&gt; typec.h)&lt;br /&gt;&lt;br /&gt; 41. Fundas of RPC.&lt;br /&gt;&lt;br /&gt; 42. Given a linked list which is sorted. How will u insert in sorted&lt;br /&gt;     way.&lt;br /&gt;&lt;br /&gt; 43. Given a linked list How will you reverse it.&lt;br /&gt;&lt;br /&gt; 44. Tell me the courses you liked and why  did you like them.&lt;br /&gt;&lt;br /&gt; 45. Give an instance in your life in which u were faced with a&lt;br /&gt;     problem and you tackled it successfully.&lt;br /&gt;&lt;br /&gt; 46. What is your ideal working environment. ( They usually&lt;br /&gt;     to hear that u can work in group also.)&lt;br /&gt;&lt;br /&gt; 47. Why do u think u are smart.&lt;br /&gt;&lt;br /&gt; 48. Questions on the projects listed on the Resume.&lt;br /&gt;&lt;br /&gt; 49. Do you want to know any thing about the company.( Try to ask some&lt;br /&gt;     relevant and interesting question).&lt;br /&gt;&lt;br /&gt; 50. How long do u want  to stay in USA and why?&lt;br /&gt;&lt;br /&gt; 51. What are your geographical preference?&lt;br /&gt;&lt;br /&gt; 52. What are your expecctations from the job.&lt;br /&gt;&lt;br /&gt; 53. Give a good data structure for having n queues ( n not fixed) in a&lt;br /&gt;     finite memory segment. You can have some data-structure separate for&lt;br /&gt;     each queue. Try to use at least 90% of the memory space.&lt;br /&gt;&lt;br /&gt; 54. Do a breadth first traversal of a tree.&lt;br /&gt;&lt;br /&gt; 55. Write code for reversing a linked list.&lt;br /&gt;&lt;br /&gt; 56. Write, efficient code for extracting unique elements from&lt;br /&gt;     a sorted list of array.  e.g. (1, 1, 3, 3, 3, 5, 5, 5, 9, 9, 9, 9) -&gt;&lt;br /&gt;     (1, 3, 5, 9).&lt;br /&gt;&lt;br /&gt; 57. C++ ( what is virtual function ?&lt;br /&gt;     what happens if an error occurs in constructor or destructor.&lt;br /&gt;     Discussion on error handling, templates, unique features of C++.&lt;br /&gt;     What is different in C++, ( compare with unix).&lt;br /&gt;&lt;br /&gt; 58. Given a list of numbers ( fixed list) Now given any other list,&lt;br /&gt;     how can you efficiently find out if there is any element in the&lt;br /&gt;     second list that is an element of the first list (fixed list).&lt;br /&gt;&lt;br /&gt; 59. GIven 3 lines of assembly code : find it is doing. IT was to find&lt;br /&gt;     absolute value.&lt;br /&gt;&lt;br /&gt; 60. If you are on a boat and you throw out a suitcase, Will the level of&lt;br /&gt;     water increase.&lt;br /&gt;&lt;br /&gt; 61. Print an integer using only putchar. Try doing it without using extra&lt;br /&gt;     storage.&lt;br /&gt;&lt;br /&gt; 62. write C code for&lt;br /&gt;     deleting an  element from a linked listy&lt;br /&gt;     traversing a linked list&lt;br /&gt;     efficient way of elimiating duplicates from an array&lt;br /&gt;&lt;br /&gt; 63. what are various problems unique to distributed databases&lt;br /&gt;&lt;br /&gt; 64. declare a void pointer&lt;br /&gt;     a)      void    *ptr;&lt;br /&gt;&lt;br /&gt; 65. make the pointer aligned to a 4 byte boundary in a efficient manner&lt;br /&gt;     a)      assign the pointer to a long number&lt;br /&gt;             and the number with 11...1100&lt;br /&gt;             add 4 to the number&lt;br /&gt;&lt;br /&gt; 66. what is  a far pointer (in DOS)&lt;br /&gt;&lt;br /&gt; 67. what is  a balanced tree&lt;br /&gt;&lt;br /&gt; 68. given a linked list with the following property&lt;br /&gt;     node2 is left child of node1, if node2 &lt; node1&lt;br /&gt;     els, it is the right child.&lt;br /&gt;&lt;br /&gt;        O P&lt;br /&gt;        |&lt;br /&gt;        |&lt;br /&gt;        O A&lt;br /&gt;        |&lt;br /&gt;        |&lt;br /&gt;        O B&lt;br /&gt;        |&lt;br /&gt;        |&lt;br /&gt;        O C&lt;br /&gt;&lt;br /&gt;        How do you convert the above linked list to the&lt;br /&gt;        form without disturbing the property. Write C code&lt;br /&gt;        for that.&lt;br /&gt;&lt;br /&gt;                        O P&lt;br /&gt;                        |&lt;br /&gt;                        |&lt;br /&gt;                        O B&lt;br /&gt;                       /                       /                        /                         O ?     O ?&lt;br /&gt;&lt;br /&gt;        determine where do A and C go&lt;br /&gt;&lt;br /&gt;&lt;br /&gt; 69. Describe the file system layout in the UNIX OS&lt;br /&gt;     a)  describe boot block, super block, inodes and data layout&lt;br /&gt;&lt;br /&gt; 70. In UNIX, are the files allocated contiguous blocks of data&lt;br /&gt;     a)      no, they might be fragmented&lt;br /&gt;     how is the fragmented data kept track of&lt;br /&gt;     a)      describe the direct blocks and indirect blocks in UNIX&lt;br /&gt;             file system&lt;br /&gt;&lt;br /&gt; 71. Write an efficient C code for 'tr' program.  'tr' has two command&lt;br /&gt;     line arguments. They both are strings of same length. tr reads an&lt;br /&gt;     input file, replaces each character in the first string with the&lt;br /&gt;     corresponding character in the second string. eg. 'tr abc xyz'&lt;br /&gt;     replaces all 'a's by 'x's, 'b's by 'y's and so on.&lt;br /&gt;     a)      have an array of length 26.&lt;br /&gt;             put 'x' in array element corr to 'a'&lt;br /&gt;             put 'y' in array element corr to 'b'&lt;br /&gt;             put 'z' in array element corr to 'c'&lt;br /&gt;             put 'd' in array element corr to 'd'&lt;br /&gt;             put 'e' in array element corr to 'e'&lt;br /&gt;             and so on.&lt;br /&gt;&lt;br /&gt;        the code&lt;br /&gt;                while (!eof)&lt;br /&gt;                {&lt;br /&gt;                        c = getc();&lt;br /&gt;                        putc(array[c - 'a']);&lt;br /&gt;                }&lt;br /&gt;&lt;br /&gt; 72. what is disk interleaving&lt;br /&gt;&lt;br /&gt; 73. why is disk interleaving adopted&lt;br /&gt;&lt;br /&gt; 74. given a new disk, how do you determine which interleaving is the best&lt;br /&gt;     a)      give 1000 read operations with each kind of interleaving&lt;br /&gt;             determine the best interleaving from the statistics&lt;br /&gt;&lt;br /&gt; 75. draw the graph with performace on one axis and 'n' on another, where&lt;br /&gt;     'n' in the 'n' in n-way disk interleaving. (a tricky question, should&lt;br /&gt;     be answered carefully)&lt;br /&gt;&lt;br /&gt; 76. I was a c++ code and was asked to find out the bug in that. The bug&lt;br /&gt;     was that he declared an object locally in a function and tried to&lt;br /&gt;     return the pointer to that object.  Since the object is local to the&lt;br /&gt;     function, it no more exists after returning from the function. The&lt;br /&gt;     pointer, therefore, is invalid outside.&lt;br /&gt;&lt;br /&gt; 77. A real life problem - A square picture is cut into 16 sqaures and&lt;br /&gt;     they are shuffled.  Write a program to rearrange the 16 squares to&lt;br /&gt;     get the original big square.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/15836190-113988971782968774?l=forthosewhomatters.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://forthosewhomatters.blogspot.com/feeds/113988971782968774/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=15836190&amp;postID=113988971782968774' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/15836190/posts/default/113988971782968774'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/15836190/posts/default/113988971782968774'/><link rel='alternate' type='text/html' href='http://forthosewhomatters.blogspot.com/2006/02/technical-interview-questions.html' title='Technical Interview Questions'/><author><name>For Those Who Matter</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-15836190.post-113988531928456932</id><published>2006-02-13T18:47:00.000-08:00</published><updated>2006-02-13T18:49:28.283-08:00</updated><title type='text'>C++/C - convert an integer to string</title><content type='html'>#include "stdafx.h"&lt;br /&gt;#include [stdlib.h]&lt;br /&gt;#include [iostream]&lt;br /&gt;&lt;br /&gt;using namespace std;&lt;br /&gt;&lt;br /&gt;int _tmain(int argc, _TCHAR* argv[])&lt;br /&gt;{&lt;br /&gt; char buffer[20] ;&lt;br /&gt; memset(buffer, '\0', 20);&lt;br /&gt; cout &lt;&lt; _itoa(2000, buffer, 10) &lt;&lt; endl;&lt;br /&gt; string str (buffer);&lt;br /&gt; cout &lt;&lt; str.size() &lt;&lt; endl;&lt;br /&gt; int i;&lt;br /&gt; cin &gt;&gt;  i;&lt;br /&gt; return 0;&lt;br /&gt;}&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/15836190-113988531928456932?l=forthosewhomatters.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://forthosewhomatters.blogspot.com/feeds/113988531928456932/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=15836190&amp;postID=113988531928456932' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/15836190/posts/default/113988531928456932'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/15836190/posts/default/113988531928456932'/><link rel='alternate' type='text/html' href='http://forthosewhomatters.blogspot.com/2006/02/cc-convert-integer-to-string.html' title='C++/C - convert an integer to string'/><author><name>For Those Who Matter</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-15836190.post-113949953100769030</id><published>2006-02-09T07:28:00.000-08:00</published><updated>2006-02-09T07:38:51.150-08:00</updated><title type='text'>WinSock - simple Client/Server</title><content type='html'>Program Flow of a simple TCP client&lt;br /&gt;1. Initialize WinSock library using WSAStartup() &lt;br /&gt;2. Create a IPPROTO_TCP SOCKET using socket() &lt;br /&gt;3. Retrieve host information using gethostbyname()/gethostbyaddr() &lt;br /&gt;4. Connect to the server using the socket we created, using connect() &lt;br /&gt;5. Send and Receive data using send()/recv() till our tcp chat is over &lt;br /&gt;6. Close the socket connection using closesocket() &lt;br /&gt;7. De-Initialize WinSock using WSACleanup() &lt;br /&gt;&lt;br /&gt;Program Flow of a simple TCP Server&lt;br /&gt;1. Initialize WinSock library using WSAStartup() &lt;br /&gt;2. Create a IPPROTO_TCP SOCKET using socket() &lt;br /&gt;3. Use bind(), bind the socket to a special port&lt;br /&gt;4. Using listen to wait for incoming connection&lt;br /&gt;5. Use accept to set up a connection with client&lt;br /&gt;6. Use send to send info to client&lt;br /&gt;7. Use closesocket to close a connection&lt;br /&gt;8. De-Initialize WinSock using WSACleanup()&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/15836190-113949953100769030?l=forthosewhomatters.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://forthosewhomatters.blogspot.com/feeds/113949953100769030/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=15836190&amp;postID=113949953100769030' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/15836190/posts/default/113949953100769030'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/15836190/posts/default/113949953100769030'/><link rel='alternate' type='text/html' href='http://forthosewhomatters.blogspot.com/2006/02/winsock-simple-clientserver.html' title='WinSock - simple Client/Server'/><author><name>For Those Who Matter</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-15836190.post-113934472791815033</id><published>2006-02-07T12:27:00.000-08:00</published><updated>2006-02-07T12:38:47.983-08:00</updated><title type='text'>Chinese characters - coding, storing and browsing</title><content type='html'>Chinese characters are encoded different from English characters. There are some special steps you have to taken when coding, storing and browsing.&lt;br /&gt;&lt;br /&gt;1. Visual studio&lt;br /&gt;You can input Chinese characters in your source codes with IME. When you save the source codes, you have to use "save as", then in the popup window, chose "encode with UTF-8 with signature". &lt;br /&gt;2. Database&lt;br /&gt;In the table field where you store Chinese characters, under the "Collation" attribute, choose "Windows collation" then select "Chines PRC".&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/15836190-113934472791815033?l=forthosewhomatters.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://forthosewhomatters.blogspot.com/feeds/113934472791815033/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=15836190&amp;postID=113934472791815033' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/15836190/posts/default/113934472791815033'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/15836190/posts/default/113934472791815033'/><link rel='alternate' type='text/html' href='http://forthosewhomatters.blogspot.com/2006/02/chinese-characters-coding-storing-and.html' title='Chinese characters - coding, storing and browsing'/><author><name>For Those Who Matter</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-15836190.post-113890624678618486</id><published>2006-02-02T10:45:00.000-08:00</published><updated>2006-02-02T15:16:56.776-08:00</updated><title type='text'>Visual Studio - Displaying an Assembly in the Add Reference Dialog Box</title><content type='html'>The Add Reference dialog box does not automatically display every assembly, even if it has been installed to the Global Assembly Cache (GAC). The Add Reference dialog box is path based, and requires a registry key to be added that specifies the location of assemblies to display.&lt;br /&gt;&lt;br /&gt;To display assemblies in the Add Reference dialog box &lt;br /&gt;&lt;br /&gt;1. Add one of the following registry keys, where [AssemblyLocation] is the directory of the assemblies that you want to appear in the Add Reference dialog box, for example, C:\\MyAssemblies.&lt;br /&gt;&lt;br /&gt;[HKEY_CURRENT_USER\SOFTWARE\Microsoft\.NETFramework\[version]\AssemblyFoldersEx\MyAssemblies]@="[AssemblyLocation]"&lt;br /&gt;&lt;br /&gt;[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETFramework\&lt;version&gt;\AssemblyFoldersEx\MyAssemblies]@="[AssemblyLocation]"&lt;br /&gt;&lt;br /&gt;Note  &lt;br /&gt;Creating the registry key under the HKEY_LOCAL_MACHINE hive allows all users to see the assemblies in the specified location in the Add Reference dialog box. Creating the registry key under the HKEY_CURRENT_USER hive only affects the setting for the current user.&lt;br /&gt; &lt;br /&gt;If AssemblyFoldersEx does not work, change it to AssemblyFolders.&lt;br /&gt;&lt;br /&gt;2. Restart Visual Studio.&lt;br /&gt;&lt;br /&gt;http://msdn2.microsoft.com/en-us/library/ftcwa60a.aspx&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/15836190-113890624678618486?l=forthosewhomatters.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://forthosewhomatters.blogspot.com/feeds/113890624678618486/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=15836190&amp;postID=113890624678618486' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/15836190/posts/default/113890624678618486'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/15836190/posts/default/113890624678618486'/><link rel='alternate' type='text/html' href='http://forthosewhomatters.blogspot.com/2006/02/visual-studio-displaying-assembly-in.html' title='Visual Studio - Displaying an Assembly in the Add Reference Dialog Box'/><author><name>For Those Who Matter</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-15836190.post-113770833906130418</id><published>2006-01-19T14:04:00.000-08:00</published><updated>2006-01-19T14:05:39.063-08:00</updated><title type='text'>Thread - background and fourground</title><content type='html'>A thread is either a background thread or a foreground thread. Background threads are identical to foreground threads, except that background threads do not prevent a process from terminating. Once all foreground threads belonging to a process have terminated, the common language runtime ends the process by invoking Abort on any background threads that are still alive.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/15836190-113770833906130418?l=forthosewhomatters.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://forthosewhomatters.blogspot.com/feeds/113770833906130418/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=15836190&amp;postID=113770833906130418' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/15836190/posts/default/113770833906130418'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/15836190/posts/default/113770833906130418'/><link rel='alternate' type='text/html' href='http://forthosewhomatters.blogspot.com/2006/01/thread-background-and-fourground.html' title='Thread - background and fourground'/><author><name>For Those Who Matter</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-15836190.post-113770817606027381</id><published>2006-01-19T14:00:00.000-08:00</published><updated>2006-01-19T14:02:56.086-08:00</updated><title type='text'>Call delegate - asynchronously and synchronously</title><content type='html'>Use IAsyncResult BeginInvoke(&lt;br /&gt;   Delegate method,&lt;br /&gt;   object[] args&lt;br /&gt;);&lt;br /&gt;&lt;br /&gt;The delegate is called asynchronously, and this method returns immediately. You can call this method from any thread. If you need the return value from a process started with this method, call EndInvoke to get the value.&lt;br /&gt;&lt;br /&gt;If you need to call the delegate synchronously, use the Invoke method instead.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/15836190-113770817606027381?l=forthosewhomatters.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://forthosewhomatters.blogspot.com/feeds/113770817606027381/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=15836190&amp;postID=113770817606027381' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/15836190/posts/default/113770817606027381'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/15836190/posts/default/113770817606027381'/><link rel='alternate' type='text/html' href='http://forthosewhomatters.blogspot.com/2006/01/call-delegate-asynchronously-and.html' title='Call delegate - asynchronously and synchronously'/><author><name>For Those Who Matter</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-15836190.post-113764303645410747</id><published>2006-01-18T19:54:00.000-08:00</published><updated>2006-02-09T07:14:14.036-08:00</updated><title type='text'>C++ - static local variable</title><content type='html'>Static local variables are not distroyed when out of scrope.&lt;br /&gt;They are stored in stack but a permanent special section.&lt;br /&gt;&lt;br /&gt;If the function is not called the first time, the initialization statement will be ignored and the value of previous call is kept.&lt;br /&gt;&lt;br /&gt;If you have the address of the variable, you can manipulate it even you are not in the scope where it is define. &lt;br /&gt;&lt;br /&gt;As such, they provide private and permanent storage for a function. When that function is invoked again, it will access the same calls variable.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/15836190-113764303645410747?l=forthosewhomatters.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://forthosewhomatters.blogspot.com/feeds/113764303645410747/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=15836190&amp;postID=113764303645410747' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/15836190/posts/default/113764303645410747'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/15836190/posts/default/113764303645410747'/><link rel='alternate' type='text/html' href='http://forthosewhomatters.blogspot.com/2006/01/c-static-local-variable.html' title='C++ - static local variable'/><author><name>For Those Who Matter</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-15836190.post-113745387925813437</id><published>2006-01-16T15:05:00.000-08:00</published><updated>2006-01-16T15:25:00.036-08:00</updated><title type='text'>CSS - Cascading Style Sheets</title><content type='html'>About CSS the most important factors are:&lt;br /&gt;&lt;br /&gt;3 Ways of defining CSS:&lt;br /&gt;1. Directly associate it with HTML elements;&lt;br /&gt;h1,h2,h3,h4,h5,h6 &lt;br /&gt;{&lt;br /&gt;color: green&lt;br /&gt;}&lt;br /&gt;2. Associate it with class selector&lt;br /&gt;p.right {text-align: right}&lt;br /&gt;p.center {text-align: center}&lt;br /&gt;When using, &lt;p class="right"&gt;&lt;br /&gt;This paragraph will be right-aligned.&lt;br /&gt;&lt;/p&gt;&lt;br /&gt;You can omit the class selector here. Then it can be applied to all html elements.&lt;br /&gt;3.Associate it with ID selector&lt;br /&gt;#green {color: green} &lt;br /&gt;The rule above will match both the h1 and the p element:&lt;br /&gt;&lt;h1 id="green"&gt;Some text&lt;/h1&gt;&lt;br /&gt;&lt;p id="green"&gt;Some text&lt;/p&gt; &lt;br /&gt;It does not have much different from the default class selector.&lt;br /&gt;ID selector can be associated with the html elements also.&lt;br /&gt;p#para1&lt;br /&gt;{&lt;br /&gt;text-align: center;&lt;br /&gt;color: red&lt;br /&gt;} &lt;br /&gt;&lt;br /&gt;3 Places of putting CSS&lt;br /&gt;1. External style sheet, defining the place inside the head element.&lt;br /&gt;&lt;head&gt;&lt;br /&gt;&lt;link rel="stylesheet" type="text/css"&lt;br /&gt;href="mystyle.css" /&gt;&lt;br /&gt;&lt;/head&gt;&lt;br /&gt;2. Internal style sheet&lt;br /&gt;&lt;head&gt;&lt;br /&gt;&lt;style type="text/css"&gt;&lt;br /&gt;hr {color: sienna}&lt;br /&gt;p {margin-left: 20px}&lt;br /&gt;body {background-image: url("images/back40.gif")}&lt;br /&gt;&lt;/style&gt;&lt;br /&gt;&lt;/head&gt; &lt;br /&gt;3.Inline styles&lt;br /&gt;&lt;p style="color: sienna; margin-left: 20px"&gt;&lt;br /&gt;This is a paragraph&lt;br /&gt;&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;Name conflicting styles from different places will be mixed and overrided.&lt;br /&gt;&lt;br /&gt;Details of what can be defined with style sheet, see the reference:&lt;br /&gt;&lt;br /&gt;http://www.w3schools.com/css/css_reference.asp&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/15836190-113745387925813437?l=forthosewhomatters.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://forthosewhomatters.blogspot.com/feeds/113745387925813437/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=15836190&amp;postID=113745387925813437' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/15836190/posts/default/113745387925813437'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/15836190/posts/default/113745387925813437'/><link rel='alternate' type='text/html' href='http://forthosewhomatters.blogspot.com/2006/01/css-cascading-style-sheets.html' title='CSS - Cascading Style Sheets'/><author><name>For Those Who Matter</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-15836190.post-113735923399405198</id><published>2006-01-15T13:05:00.000-08:00</published><updated>2006-01-15T13:07:14.013-08:00</updated><title type='text'>Abstract Classes vs. Interfaces</title><content type='html'>If you anticipate creating multiple versions of your component, create an abstract class. Abstract classes provide a simple and easy way to version your components. By updating the base class, all inheriting classes are automatically updated with the change. Interfaces, on the other hand, cannot be changed once created. If a new version of an interface is required, you must create a whole new interface. &lt;br /&gt;&lt;br /&gt;If the functionality you are creating will be useful across a wide range of disparate objects, use an interface. Abstract classes should be used primarily for objects that are closely related, whereas interfaces are best suited for providing common functionality to unrelated classes. &lt;br /&gt;&lt;br /&gt;If you are designing small, concise bits of functionality, use interfaces. If you are designing large functional units, use an abstract class. &lt;br /&gt;&lt;br /&gt;If you want to provide common, implemented functionality among all implementations of your component, use an abstract class. Abstract classes allow you to partially implement your class, whereas interfaces contain no implementation for any members.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/15836190-113735923399405198?l=forthosewhomatters.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://forthosewhomatters.blogspot.com/feeds/113735923399405198/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=15836190&amp;postID=113735923399405198' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/15836190/posts/default/113735923399405198'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/15836190/posts/default/113735923399405198'/><link rel='alternate' type='text/html' href='http://forthosewhomatters.blogspot.com/2006/01/abstract-classes-vs-interfaces.html' title='Abstract Classes vs. Interfaces'/><author><name>For Those Who Matter</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-15836190.post-113713183045841876</id><published>2006-01-12T19:29:00.000-08:00</published><updated>2006-01-12T21:57:10.506-08:00</updated><title type='text'>Implement a binary search tree</title><content type='html'>A sorted list make a search faster and easier. But maintaining a sorted list may be costly especially if you use a linked list. &lt;br /&gt;&lt;br /&gt;In this case, a binary search tree will be very helpful. A binary search tree contains a root node, each node contains a data part and two pointers(left, right) pointing to its children nodes.(if not leaf nodes). Usually the right child is less than the parent node while the right pointer is bigger.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;public class Tree_Node&lt;br /&gt;{&lt;br /&gt; public IComparable data&lt;br /&gt; {&lt;br /&gt;   set{...};&lt;br /&gt;   get{...};&lt;br /&gt; }IComparable _data;&lt;br /&gt; public Tree_Node left&lt;br /&gt; {&lt;br /&gt; ...&lt;br /&gt; }Tree_Node _left;&lt;br /&gt; poublic Tree_Node right&lt;br /&gt; {&lt;br /&gt;  ...&lt;br /&gt; }Tree_Node _right;&lt;br /&gt; public Tree_Node(Comparable x){ _data = x};&lt;br /&gt;} &lt;br /&gt;&lt;br /&gt;interface SearchTree&lt;br /&gt;{&lt;br /&gt; void insert(IComparable x);&lt;br /&gt; void remove(IComparable x);&lt;br /&gt; Tree_Node find(IComparable x);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;public class BinarySearchTree : SearchTree&lt;br /&gt;{&lt;br /&gt;  public Tree_Node root&lt;br /&gt;  { ...&lt;br /&gt;  }Tree_Node _root;&lt;br /&gt;  pubic BinarySearchTree () {_root = null;}&lt;br /&gt;  void inert(IComparable x)&lt;br /&gt;  {&lt;br /&gt;    if(_root == null)&lt;br /&gt;    {&lt;br /&gt;      _root = new Tree_Node(x);&lt;br /&gt;    }else&lt;br /&gt;    {&lt;br /&gt;       insertNode(_root, x);&lt;br /&gt;    }&lt;br /&gt;  }&lt;br /&gt;  void insertNode(Tree_Node root, Icomparable x)&lt;br /&gt;  {&lt;br /&gt;    if(root.data.CompareTo(x) &gt; 0)&lt;br /&gt;    {&lt;br /&gt;      if(root.left != null)&lt;br /&gt;         insertNode(root.left, x);&lt;br /&gt;      else&lt;br /&gt;         root.left = new Tree_Node(x);&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    if(root.data.CompareTo(x) &lt; 0)&lt;br /&gt;    {&lt;br /&gt;      if(root.right != null)&lt;br /&gt;         insertNode(root.right, x);&lt;br /&gt;      else&lt;br /&gt;         root.right = new Tree_Node(x);&lt;br /&gt;    }&lt;br /&gt;    &lt;br /&gt;    if(root.data.CompareTo(x) == 0) throw new Exception("Duplicated Item");&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  Tree_Node find(IComparable x)&lt;br /&gt;  {&lt;br /&gt;    Tree_Node current = root;&lt;br /&gt;    while(current != 0 &amp;&amp; x.CompareTo(current.data) != 0)&lt;br /&gt;    {&lt;br /&gt;       if(current.CompareTo(x) &gt; 0) current = current.right;&lt;br /&gt;       else current = current.left;&lt;br /&gt;    }&lt;br /&gt;    return current;&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  Tree_Node findMin(Tree_Node node)&lt;br /&gt;  {&lt;br /&gt;    if(node == null) throw Exception("");&lt;br /&gt;    while(node.left != null)&lt;br /&gt;       node = node.left;&lt;br /&gt;    return node;&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  void remove(IComparable x)&lt;br /&gt;  {&lt;br /&gt;    remove(x, root);&lt;br /&gt;  }&lt;br /&gt;  void removeMin(Tree_Node node)&lt;br /&gt;{&lt;br /&gt;  TreeNode minNode = findMin(node);&lt;br /&gt;  TreeNode parent = findParent(minNode);&lt;br /&gt;  parent.left = minNode.right;&lt;br /&gt;}&lt;br /&gt;    Tree_Node findParent(TreeNode node)&lt;br /&gt;  {&lt;br /&gt;    Tree_Node current = root;&lt;br /&gt;    Tree_Node parent = null;&lt;br /&gt;    if(node == null) throw ...;&lt;br /&gt;    while(current != 0 &amp;&amp; node.data.CompareTo(current.data) != 0)&lt;br /&gt;    {&lt;br /&gt;       parent = current;&lt;br /&gt;       if(current.CompareTo(x) &gt; 0) current = current.right;&lt;br /&gt;       else current = current.left;&lt;br /&gt;    }&lt;br /&gt;    return current;&lt;br /&gt;  }&lt;br /&gt;  void remove(Icomparable x, Tree_Node root)&lt;br /&gt;  {&lt;br /&gt;    if(root == null) throw Exception;&lt;br /&gt;    if(x.CompareTo(root.data) &gt; 0)&lt;br /&gt;        remove(x, root.right);&lt;br /&gt;    else if(x.CompareTo(root.data) &lt; 0)&lt;br /&gt;        remove(x, root.left);&lt;br /&gt;    else if(node.left != null &amp;&amp; node.rgiht != null)&lt;br /&gt;    {&lt;br /&gt;       node.data = findMin(node.right);&lt;br /&gt;       removeMin(node.right);&lt;br /&gt;    }&lt;br /&gt;    else&lt;br /&gt;    {&lt;br /&gt;       node = (node.left == null) ? node.right : node.left;&lt;br /&gt;    }&lt;br /&gt;  }&lt;br /&gt;   &lt;br /&gt;  &lt;br /&gt;}&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/15836190-113713183045841876?l=forthosewhomatters.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://forthosewhomatters.blogspot.com/feeds/113713183045841876/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=15836190&amp;postID=113713183045841876' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/15836190/posts/default/113713183045841876'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/15836190/posts/default/113713183045841876'/><link rel='alternate' type='text/html' href='http://forthosewhomatters.blogspot.com/2006/01/implement-binary-search-tree.html' title='Implement a binary search tree'/><author><name>For Those Who Matter</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-15836190.post-113712264156978677</id><published>2006-01-12T16:51:00.000-08:00</published><updated>2006-01-12T19:24:01.643-08:00</updated><title type='text'>Write a garbage collector for C++</title><content type='html'>First you declare a smart pointer&lt;br /&gt;&lt;br /&gt;template&lt;class T&gt;class auto_ptr&lt;br /&gt;{&lt;br /&gt;   T* ptr;&lt;br /&gt;  public:&lt;br /&gt;   explicit auto_ptr(T* p = 0) : ptr(p){}&lt;br /&gt;   ~auto_ptr{ delete ptr; }&lt;br /&gt;   T&amp; operator*() { return *ptr;}&lt;br /&gt;   T* operator-&gt;() { return ptr; }&lt;br /&gt;   //&lt;br /&gt;   ...&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;This simple smarter pointer will deallocate memory automatically when it is out of scope. &lt;br /&gt;&lt;br /&gt;But if we just leave it like this, it will cause problems, mainly dangling pointers. For example, you assign the object, or you return this object in a function. In either case, default copy contructor will called and a shallow copy is made. &lt;br /&gt;&lt;br /&gt;So we definitely need a copy structor. But this copy structor can do a deep copy, thus we wont have dangling pointers problem.(But we dont know the detail of T, or we need T itself has a copy contructor correctly implmented also?).&lt;br /&gt;&lt;br /&gt;The above way does not use memory efficiently and has some uncertainities. &lt;br /&gt;&lt;br /&gt;Thus we will consider the solution of shallow copy, at the same time add a reference counter, deallocate memory only if there is no reference.&lt;br /&gt;&lt;br /&gt;First we need add a private struct counter in the smart pointer.&lt;br /&gt;&lt;br /&gt;template &lt;class X&gt; class counted_ptr&lt;br /&gt;{&lt;br /&gt;&lt;br /&gt;private:&lt;br /&gt;    struct counter {&lt;br /&gt;        counter(X* p = 0, unsigned c = 1) : ptr(p), count(c) {}&lt;br /&gt;        X*          ptr;&lt;br /&gt;        unsigned    count;&lt;br /&gt;    }* itsCounter;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;Then we need change the constructor, destructor&lt;br /&gt;&lt;br /&gt;explicit counted_ptr(T* p = 0) // allocate a new counter&lt;br /&gt;        : itsCounter(0) {if (p) itsCounter = new counter(p);}&lt;br /&gt;&lt;br /&gt;~counted_ptr{release();}&lt;br /&gt;&lt;br /&gt;private :&lt;br /&gt;  release()&lt;br /&gt;  {&lt;br /&gt;       // decrement the count, delete if it is 0&lt;br /&gt;        if (itsCounter) {&lt;br /&gt;            if (--itsCounter-&gt;count == 0) {&lt;br /&gt;                delete itsCounter-&gt;ptr;&lt;br /&gt;                delete itsCounter;&lt;br /&gt;            }&lt;br /&gt;            itsCounter = 0;&lt;br /&gt;        }&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;Not enough yet, we need handle copy constructor and assignment operator, so that we will keep track the reference to the real pointer.&lt;br /&gt;&lt;br /&gt;counted_ptr(const counted_ptr&amp; r) throw()&lt;br /&gt;{acquire(r.itsCounter);}&lt;br /&gt;&lt;br /&gt;counted_ptr&amp; operator=(const counted_ptr&amp; r)&lt;br /&gt;{&lt;br /&gt;        if (this != &amp;r) {&lt;br /&gt;            release();&lt;br /&gt;            acquire(r.itsCounter);&lt;br /&gt;        }&lt;br /&gt;        return *this;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;    void acquire(counter* c) throw()&lt;br /&gt;    { // increment the count&lt;br /&gt;        itsCounter = c;&lt;br /&gt;        if (c) ++c-&gt;count;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;If you are careful, you will notice in the assignment operation, it checks to see whether it is same oject, other wise relasee the old one.&lt;br /&gt;&lt;br /&gt;You can see that each possible way of referencing is tracked.&lt;br /&gt;&lt;br /&gt;So far, the automactially memory management is done.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/15836190-113712264156978677?l=forthosewhomatters.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://forthosewhomatters.blogspot.com/feeds/113712264156978677/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=15836190&amp;postID=113712264156978677' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/15836190/posts/default/113712264156978677'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/15836190/posts/default/113712264156978677'/><link rel='alternate' type='text/html' href='http://forthosewhomatters.blogspot.com/2006/01/write-garbage-collector-for-c.html' title='Write a garbage collector for C++'/><author><name>For Those Who Matter</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-15836190.post-113710151366493848</id><published>2006-01-12T13:31:00.000-08:00</published><updated>2006-01-12T15:59:51.110-08:00</updated><title type='text'>garbage collectors, tree, array, why, challenge</title><content type='html'>http://msdn.microsoft.com/msdnmag/issues/1100/GCI/default.aspx&lt;br /&gt;&lt;br /&gt;http://msdn.microsoft.com/msdnmag/issues/1200/GCI2/default.aspx&lt;br /&gt;&lt;br /&gt;NextObjPtr&lt;br /&gt;&lt;br /&gt;new operator&lt;br /&gt;&lt;br /&gt;the global and static object pointers in an application are considered part of the application's roots.&lt;br /&gt;&lt;br /&gt;http://ootips.org/yonat/4dev/smart-pointers.html&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/15836190-113710151366493848?l=forthosewhomatters.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://forthosewhomatters.blogspot.com/feeds/113710151366493848/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=15836190&amp;postID=113710151366493848' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/15836190/posts/default/113710151366493848'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/15836190/posts/default/113710151366493848'/><link rel='alternate' type='text/html' href='http://forthosewhomatters.blogspot.com/2006/01/garbage-collectors-tree-array-why.html' title='garbage collectors, tree, array, why, challenge'/><author><name>For Those Who Matter</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-15836190.post-113709645263808402</id><published>2006-01-12T11:43:00.000-08:00</published><updated>2006-01-12T12:07:32.686-08:00</updated><title type='text'>ASP.NET User control vs. Custom Control</title><content type='html'>User control inherits from System.Web.UI.UserControl. It contains two parts a .ascx file and its code behind. All the code there follows same format of a normal aspx file. &lt;br /&gt;&lt;br /&gt;To use a User control, you have to use a register directive that shows where the source file is. In the main code behind, you can treat it as a normal server control.&lt;br /&gt;&lt;br /&gt;Custom control is derived from System.Web.UI.Control or System.Web.UI.WebControl. In each case, you have to override its Render method that takes one parameter that is System.Web.UI.HtmlTextWriter that will output the contents of the custom control. Web user control does not contain a visisble layout. You have to layaout the controls using html table yourself. You can either write html table as literals in CreateChildnControls or Put them in the Render method.&lt;br /&gt;&lt;br /&gt;Deriving from web control makes ParseChildrenAttribute true.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/15836190-113709645263808402?l=forthosewhomatters.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://forthosewhomatters.blogspot.com/feeds/113709645263808402/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=15836190&amp;postID=113709645263808402' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/15836190/posts/default/113709645263808402'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/15836190/posts/default/113709645263808402'/><link rel='alternate' type='text/html' href='http://forthosewhomatters.blogspot.com/2006/01/aspnet-user-control-vs-custom-control.html' title='ASP.NET User control vs. Custom Control'/><author><name>For Those Who Matter</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-15836190.post-113703858293527554</id><published>2006-01-11T20:01:00.000-08:00</published><updated>2006-01-11T20:03:02.953-08:00</updated><title type='text'>Win32 - Summary of Synchronization Objects</title><content type='html'>Critical Section&lt;br /&gt;Critical sections are one of the more primitive synchronization objects in Win32. They synchronize exclusive access to shared data between threads within a single process. As long as no contention for gaining access to a critical section exists, the critical section code runs entirely in user mode, making it extremely fast. You don't have to pay the speed penalty of transitioning between user and kernel mode. When there is contention for a critical section, however, all is not lost; it simply falls back to using a kernel event object for synchronization. Because events are kernel objects, when there is contention, the relatively expensive transition to kernel mode must be made. But since the thread will block anyway, this transition time isn't usually very significant compared to the amount of time the thread is actually blocked. Because the critical section does not have a named kernel object associated with it, one of its main disadvantages is that it cannot synchronize access between processes.&lt;br /&gt;&lt;br /&gt;Mutex&lt;br /&gt;In Win32, a mutex is a kernel object. Implementing the mutex as a kernel object solves the critical section's main disadvantage. Mutexes can synchronize between processes, but this ability comes at the sake of speed. Each time a process calls a wait function such as WaitForSingleObject on a mutex, the relatively expensive transition between user mode and kernel mode is made. When there is no contention for the shared resource, and the mutex is waited on and released numerous times, the time for this transition can add up and increase the running time of the application. Like critical sections, mutexes can only be used to synchronize exclusive access.&lt;br /&gt;&lt;br /&gt;Semaphore&lt;br /&gt;Semaphores are very similar to mutexes. Like mutexes, semaphores are implemented as kernel objects. This gives them the same advantage of working across processes, and the same disadvantage of being relatively slow. However, a mutex and a semaphore differ in that a semaphore can do more than just provide exclusive access to shared data. Semaphores can be used for resource counting. Where mutexes and critical sections allow only one thread to gain access to a shared resource at a time, semaphores allow a set number of threads to gain access to a shared resource. Additionally, Windows CE does not currently support semaphores, which makes porting applications that rely heavily on semaphores to Windows CE more difficult.&lt;br /&gt;&lt;br /&gt;Event&lt;br /&gt;Events are primitive kernel synchronization objects on which other synchronization objects can be built. By themselves they are relatively slow, but they can synchronize access between processes by using named events. Depending on how they are used, events are capable of providing resource counting, but do not keep track of the count by themselves.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/15836190-113703858293527554?l=forthosewhomatters.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://forthosewhomatters.blogspot.com/feeds/113703858293527554/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=15836190&amp;postID=113703858293527554' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/15836190/posts/default/113703858293527554'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/15836190/posts/default/113703858293527554'/><link rel='alternate' type='text/html' href='http://forthosewhomatters.blogspot.com/2006/01/win32-summary-of-synchronization.html' title='Win32 - Summary of Synchronization Objects'/><author><name>For Those Who Matter</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-15836190.post-113703763787626410</id><published>2006-01-11T19:12:00.000-08:00</published><updated>2006-01-11T19:47:17.933-08:00</updated><title type='text'>User-Level vs. Kernel Threads</title><content type='html'>User-Level managed by application, while kernel-level managed by kernel.&lt;br /&gt;Kernel not aware of user-level thread, while kernel-level consumes kernel resource&lt;br /&gt;Context switching with user level thread is cheaper.&lt;br /&gt;There is no limit on creating user level threads, but kernel-level is limited by kernel resources. &lt;br /&gt;Kernel level is simpler to user.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/15836190-113703763787626410?l=forthosewhomatters.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://forthosewhomatters.blogspot.com/feeds/113703763787626410/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=15836190&amp;postID=113703763787626410' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/15836190/posts/default/113703763787626410'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/15836190/posts/default/113703763787626410'/><link rel='alternate' type='text/html' href='http://forthosewhomatters.blogspot.com/2006/01/user-level-vs-kernel-threads.html' title='User-Level vs. Kernel Threads'/><author><name>For Those Who Matter</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-15836190.post-113703551562008732</id><published>2006-01-11T18:41:00.000-08:00</published><updated>2006-01-11T19:12:01.943-08:00</updated><title type='text'>OS - thread and process</title><content type='html'>Process - unit of resource allocation. &lt;br /&gt;A thread has no data segment or heap. A process has code/data/heap &amp; other segments.&lt;br /&gt;A thread cannot live on its own, it must live within a process. There must be at lease one thread in a process.&lt;br /&gt;There can be more than one thread in a process, the first thread calls main &amp; has the process's stack. Threads with a process share code/data/heap, share I/O, but each has its own stack&amp;registers.&lt;br /&gt;If a thread dies, its stack is reclaimed. If a process dies, its resources are reclaimed &amp;all threads die.&lt;br /&gt;&lt;br /&gt;Context switching is more expensive with process than thread.&lt;br /&gt;&lt;br /&gt;Creating a new process is costly - all of the structures (eg. page tables) must be allocated.&lt;br /&gt;&lt;br /&gt;Communicating between process is costly - most communication goes through the OS.&lt;br /&gt;&lt;br /&gt;A thread is abound to a single process. Threads are the unit of scheduling. Processes are containers in which threads execute.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/15836190-113703551562008732?l=forthosewhomatters.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://forthosewhomatters.blogspot.com/feeds/113703551562008732/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=15836190&amp;postID=113703551562008732' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/15836190/posts/default/113703551562008732'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/15836190/posts/default/113703551562008732'/><link rel='alternate' type='text/html' href='http://forthosewhomatters.blogspot.com/2006/01/os-thread-and-process.html' title='OS - thread and process'/><author><name>For Those Who Matter</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-15836190.post-113692993773174456</id><published>2006-01-10T13:48:00.000-08:00</published><updated>2006-01-10T13:52:18.896-08:00</updated><title type='text'>Demanding Security Permissions in C#</title><content type='html'>There are two ways to demand security permissions in C#: &lt;br /&gt;&lt;br /&gt;Imperatively: Using calls to permission classes in the .NET Framework &lt;br /&gt;Declaratively: Using security permission attributes &lt;br /&gt;&lt;br /&gt;Example 1: Imperative Security&lt;br /&gt;The following is an example of using .NET Framework calls to deny the UnmanagedCode permission.&lt;br /&gt;&lt;br /&gt;// ImperativeSecurity.cs&lt;br /&gt;using System;&lt;br /&gt;using System.Security;&lt;br /&gt;using System.Security.Permissions;&lt;br /&gt;using System.Runtime.InteropServices;&lt;br /&gt;&lt;br /&gt;class NativeMethods&lt;br /&gt;{&lt;br /&gt;    // This is a call to unmanaged code. Executing this method requires &lt;br /&gt;    // the UnmanagedCode security permission. Without this permission&lt;br /&gt;    // an attempt to call this method will throw a SecurityException:&lt;br /&gt;    [DllImport("msvcrt.dll")]&lt;br /&gt;    public static extern int puts(string str);&lt;br /&gt;    [DllImport("msvcrt.dll")]&lt;br /&gt;    internal static extern int _flushall();&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;class MainClass&lt;br /&gt;{&lt;br /&gt;    private static void CallUnmanagedCodeWithoutPermission()&lt;br /&gt;    {&lt;br /&gt;        // Create a security permission object to describe the&lt;br /&gt;        // UnmanagedCode permission:&lt;br /&gt;        SecurityPermission perm = &lt;br /&gt;           new SecurityPermission(SecurityPermissionFlag.UnmanagedCode);&lt;br /&gt;&lt;br /&gt;        // Deny the UnmanagedCode from our current set of permissions.&lt;br /&gt;        // Any method that is called on this thread until this method &lt;br /&gt;        // returns will be denied access to unmanaged code.&lt;br /&gt;        // Even though the CallUnmanagedCodeWithPermission method&lt;br /&gt;        // is called from a stack frame that already&lt;br /&gt;        // calls Assert for unmanaged code, you still cannot call native&lt;br /&gt;        // code. Because you use Deny here, the permission gets &lt;br /&gt;        // overwritten.&lt;br /&gt;        perm.Deny();&lt;br /&gt;&lt;br /&gt;        try&lt;br /&gt;        {&lt;br /&gt;            Console.WriteLine("Attempting to call unmanaged code without permission.");&lt;br /&gt;            NativeMethods.puts("Hello World!");&lt;br /&gt;            NativeMethods._flushall();&lt;br /&gt;            Console.WriteLine("Called unmanaged code without permission. Whoops!");&lt;br /&gt;        }&lt;br /&gt;        catch (SecurityException)&lt;br /&gt;        {&lt;br /&gt;            Console.WriteLine("Caught Security Exception attempting to call unmanaged code.");&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    private static void CallUnmanagedCodeWithPermission()&lt;br /&gt;    {&lt;br /&gt;        // Create a security permission object to describe the&lt;br /&gt;        // UnmanagedCode permission:&lt;br /&gt;        SecurityPermission perm = &lt;br /&gt;           new SecurityPermission(SecurityPermissionFlag.UnmanagedCode);&lt;br /&gt;&lt;br /&gt;        // Check that you have permission to access unmanaged code.&lt;br /&gt;        // If you don't have permission to access unmanaged code, then&lt;br /&gt;        // this call will throw a SecurityException.&lt;br /&gt;        // Even though the CallUnmanagedCodeWithPermission method&lt;br /&gt;        // is called from a stack frame that already&lt;br /&gt;        // calls Assert for unmanaged code, you still cannot call native&lt;br /&gt;        // code. Because you use Deny here, the permission gets &lt;br /&gt;        // overwritten.&lt;br /&gt;        perm.Assert();&lt;br /&gt;&lt;br /&gt;        try&lt;br /&gt;        {&lt;br /&gt;            Console.WriteLine("Attempting to call unmanaged code with permission.");&lt;br /&gt;            NativeMethods.puts("Hello World!");&lt;br /&gt;            NativeMethods._flushall();&lt;br /&gt;            Console.WriteLine("Called unmanaged code with permission.");&lt;br /&gt;        }&lt;br /&gt;        catch (SecurityException)&lt;br /&gt;        {&lt;br /&gt;            Console.WriteLine("Caught Security Exception attempting to call unmanaged code. Whoops!");&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    public static void Main() &lt;br /&gt;    {&lt;br /&gt;        // The method itself will call the security permission Deny &lt;br /&gt;        // for unmanaged code, which will override the Assert permission&lt;br /&gt;        // in this stack frame.&lt;br /&gt;        SecurityPermission perm = new &lt;br /&gt;            SecurityPermission(SecurityPermissionFlag.UnmanagedCode);&lt;br /&gt;        perm.Assert();&lt;br /&gt;        CallUnmanagedCodeWithoutPermission();&lt;br /&gt;&lt;br /&gt;        // The method itself will call the security permission Assert&lt;br /&gt;        // for unmanaged code, which will override the Deny permission in&lt;br /&gt;        // this stack frame.&lt;br /&gt;        perm.Deny();&lt;br /&gt;        CallUnmanagedCodeWithPermission();&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;Example 2: Declarative Security&lt;br /&gt;This is the same example using attributes for the security permissions.&lt;br /&gt;&lt;br /&gt;// DeclarativeSecurity.cs&lt;br /&gt;using System;&lt;br /&gt;using System.Security;&lt;br /&gt;using System.Security.Permissions;&lt;br /&gt;using System.Runtime.InteropServices;&lt;br /&gt;&lt;br /&gt;class NativeMethods&lt;br /&gt;{&lt;br /&gt;    // This is a call to unmanaged code. Executing this method requires &lt;br /&gt;    // the UnmanagedCode security permission. Without this permission,&lt;br /&gt;    // an attempt to call this method will throw a SecurityException:&lt;br /&gt;    [DllImport("msvcrt.dll")]&lt;br /&gt;    public static extern int puts(string str);&lt;br /&gt;    [DllImport("msvcrt.dll")]&lt;br /&gt;    internal static extern int _flushall();&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;class MainClass&lt;br /&gt;{&lt;br /&gt;    // The security permission attached to this method will deny the&lt;br /&gt;    // UnmanagedCode permission from the current set of permissions for&lt;br /&gt;    // the duration of the call to this method:&lt;br /&gt;    // Even though the CallUnmanagedCodeWithoutPermission method is&lt;br /&gt;    // called from a stack frame that already calls&lt;br /&gt;    // Assert for unmanaged code, you still cannot call native code.&lt;br /&gt;    // Because this function is attached with the Deny permission for&lt;br /&gt;    // unmanaged code, the permission gets overwritten.&lt;br /&gt;    [SecurityPermission(SecurityAction.Deny, Flags = &lt;br /&gt;       SecurityPermissionFlag.UnmanagedCode)]&lt;br /&gt;    private static void CallUnmanagedCodeWithoutPermission()&lt;br /&gt;    {&lt;br /&gt;        try&lt;br /&gt;        {&lt;br /&gt;            Console.WriteLine("Attempting to call unmanaged code without permission.");&lt;br /&gt;            NativeMethods.puts("Hello World!");&lt;br /&gt;            NativeMethods._flushall();&lt;br /&gt;            Console.WriteLine("Called unmanaged code without permission. Whoops!");&lt;br /&gt;        }&lt;br /&gt;        catch (SecurityException)&lt;br /&gt;        {&lt;br /&gt;            Console.WriteLine("Caught Security Exception attempting to call unmanaged code.");&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    // The security permission attached to this method will force a &lt;br /&gt;    // runtime check for the unmanaged code permission whenever&lt;br /&gt;    // this method is called. If the caller does not have unmanaged code&lt;br /&gt;    // permission, then the call will generate a Security Exception.&lt;br /&gt;    // Even though the CallUnmanagedCodeWithPermission method is called&lt;br /&gt;    // from a stack frame that already calls&lt;br /&gt;    // Deny for unmanaged code, it will not prevent you from calling&lt;br /&gt;    // native code. Because this method is attached with the Assert&lt;br /&gt;    // permission for unmanaged code, the permission gets overwritten.&lt;br /&gt;    [SecurityPermission(SecurityAction.Assert, Flags = &lt;br /&gt;       SecurityPermissionFlag.UnmanagedCode)]&lt;br /&gt;    private static void CallUnmanagedCodeWithPermission()&lt;br /&gt;    {&lt;br /&gt;        try&lt;br /&gt;        {&lt;br /&gt;            Console.WriteLine("Attempting to call unmanaged code with permission.");&lt;br /&gt;            NativeMethods.puts("Hello World!");&lt;br /&gt;            NativeMethods._flushall();&lt;br /&gt;            Console.WriteLine("Called unmanaged code with permission.");&lt;br /&gt;        }&lt;br /&gt;        catch (SecurityException)&lt;br /&gt;        {&lt;br /&gt;            Console.WriteLine("Caught Security Exception attempting to call unmanaged code. Whoops!");&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    public static void Main() &lt;br /&gt;    {&lt;br /&gt;        SecurityPermission perm = new&lt;br /&gt;            SecurityPermission(SecurityPermissionFlag.UnmanagedCode);&lt;br /&gt;&lt;br /&gt;        // The method itself is attached with the security permission &lt;br /&gt;        // Deny for unmanaged code, which will override&lt;br /&gt;        // the Assert permission in this stack frame.&lt;br /&gt;        perm.Assert();&lt;br /&gt;        CallUnmanagedCodeWithoutPermission();&lt;br /&gt;&lt;br /&gt;        // The method itself is attached with the security permission&lt;br /&gt;        // Assert for unmanaged code, which will override the Deny &lt;br /&gt;        // permission in this stack frame.&lt;br /&gt;        perm.Deny();&lt;br /&gt;        CallUnmanagedCodeWithPermission();&lt;br /&gt;    }&lt;br /&gt;}&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/15836190-113692993773174456?l=forthosewhomatters.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://forthosewhomatters.blogspot.com/feeds/113692993773174456/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=15836190&amp;postID=113692993773174456' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/15836190/posts/default/113692993773174456'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/15836190/posts/default/113692993773174456'/><link rel='alternate' type='text/html' href='http://forthosewhomatters.blogspot.com/2006/01/demanding-security-permissions-in-c.html' title='Demanding Security Permissions in C#'/><author><name>For Those Who Matter</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-15836190.post-113692422801579164</id><published>2006-01-10T10:55:00.000-08:00</published><updated>2006-01-10T12:17:08.053-08:00</updated><title type='text'>HTTP module</title><content type='html'>An HttpModule is an assembly that implements the &lt;a href="http://msdn.microsoft.com/library/en-us/cpref/html/frlrfSystemWebIHttpModuleClassTopic.asp"&gt;IHttpModule&lt;/a&gt; interface and handles events.&lt;br /&gt;&lt;br /&gt;[C#]&lt;br /&gt;using System;&lt;br /&gt;using System.Web; &lt;br /&gt;using System.Collections;&lt;br /&gt;&lt;br /&gt;public class HelloWorldModule : IHttpModule {&lt;br /&gt;    public String ModuleName { &lt;br /&gt;        get { return "HelloWorldModule"; } &lt;br /&gt;    }    &lt;br /&gt;    &lt;br /&gt;    // In the Init function, register for HttpApplication &lt;br /&gt;    // events by adding your handlers.&lt;br /&gt;    public void Init(HttpApplication application) {&lt;br /&gt;        application.BeginRequest += (new EventHandler(this.Application_BeginRequest));&lt;br /&gt;        application.EndRequest += (new EventHandler(this.Application_EndRequest));&lt;br /&gt;    }&lt;br /&gt;    &lt;br /&gt;    // Your BeginRequest event handler.&lt;br /&gt;    private void Application_BeginRequest(Object source, EventArgs e) {&lt;br /&gt;        HttpApplication application = (HttpApplication)source;&lt;br /&gt;        HttpContext context = application.Context;&lt;br /&gt;        context.Response.Write("&lt;h1&gt;&lt;font color=red&gt;HelloWorldModule: Beginning of Request&lt;/font&gt;&lt;/h1&gt;&lt;hr&gt;");&lt;br /&gt;    }&lt;br /&gt;    &lt;br /&gt;    // Your EndRequest event handler.&lt;br /&gt;    private void Application_EndRequest(Object source, EventArgs e) {&lt;br /&gt;        HttpApplication application = (HttpApplication)source;&lt;br /&gt;        HttpContext context = application.Context;&lt;br /&gt;        context.Response.Write("&lt;hr&gt;&lt;h1&gt;&lt;font color=red&gt;HelloWorldModule: End of Request&lt;/font&gt;&lt;/h1&gt;");&lt;br /&gt;    }        &lt;br /&gt;    &lt;br /&gt;    public void Dispose() &lt;br /&gt;    {&lt;br /&gt;    }&lt;br /&gt;}&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/15836190-113692422801579164?l=forthosewhomatters.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://forthosewhomatters.blogspot.com/feeds/113692422801579164/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=15836190&amp;postID=113692422801579164' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/15836190/posts/default/113692422801579164'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/15836190/posts/default/113692422801579164'/><link rel='alternate' type='text/html' href='http://forthosewhomatters.blogspot.com/2006/01/http-module.html' title='HTTP module'/><author><name>For Those Who Matter</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-15836190.post-113677664013781848</id><published>2006-01-08T19:09:00.000-08:00</published><updated>2006-01-08T19:17:20.176-08:00</updated><title type='text'>Libraries ---- ATL server, STL</title><content type='html'>ATL Server :&lt;br /&gt;&lt;br /&gt;. Active template Libary&lt;br /&gt;. a set of native C++ classes&lt;br /&gt;. To create high performance native code web applications and XML web services&lt;br /&gt;. .SRF file means server response file. It is a tag file which is used togher with dlls written with ATL server.&lt;br /&gt;&lt;br /&gt;STL:&lt;br /&gt;&lt;br /&gt;.Standard template libraies&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/15836190-113677664013781848?l=forthosewhomatters.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://forthosewhomatters.blogspot.com/feeds/113677664013781848/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=15836190&amp;postID=113677664013781848' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/15836190/posts/default/113677664013781848'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/15836190/posts/default/113677664013781848'/><link rel='alternate' type='text/html' href='http://forthosewhomatters.blogspot.com/2006/01/libraries-atl-server-stl.html' title='Libraries ---- ATL server, STL'/><author><name>For Those Who Matter</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-15836190.post-113677478767060097</id><published>2006-01-08T18:01:00.000-08:00</published><updated>2006-01-08T18:46:27.730-08:00</updated><title type='text'>IP, UDP and TCP</title><content type='html'>IP (Internet Protocol) belongs to newwork layer. Two most important fields in IP4 Datagram are: 32bit source IP Address and 32 bit Destination IP Address. The Data Field contains the tranport-layer segment - TCP or UDP) to be delivered to the destination.&lt;br /&gt;&lt;br /&gt;UDP(User Datagram Protocol) Two most important fields in a UDP segment are Source port # and Dest Port #. These are very important information for (multiplexing and demultiplexing).&lt;br /&gt;&lt;br /&gt;TCP (Transmission Control Protocol), comparing to UDP, TCP is a reliable protocol.  In order to make the transmission more reliable, TCP adds more fields into its segment Header area. Some of the most important fields are:&lt;br /&gt;&lt;br /&gt;32 bit sequence number&lt;br /&gt;32 bit acknowledgement number - which is the next sequence nubmer of the next byte a host is expecting from the other host.&lt;br /&gt;These two numbers are used for implementing a reliable data transfer service.&lt;br /&gt;&lt;br /&gt;16bit window size field is used for flowing control so that it wont flood the receiver's buffer.&lt;br /&gt;FLAG fields (RST, SYN, FIN...) are used for conection set up and teardonw. To establish a TCP connection, client sends a SYN request first with a sequence number (CSN), server replies with a SYNACK with a sequence number also and expecting client's CSN+1 byte, then client sends a ACk to SYNACK with a ack number (SSN + 1). This is called three-way handshake.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/15836190-113677478767060097?l=forthosewhomatters.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://forthosewhomatters.blogspot.com/feeds/113677478767060097/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=15836190&amp;postID=113677478767060097' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/15836190/posts/default/113677478767060097'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/15836190/posts/default/113677478767060097'/><link rel='alternate' type='text/html' href='http://forthosewhomatters.blogspot.com/2006/01/ip-udp-and-tcp.html' title='IP, UDP and TCP'/><author><name>For Those Who Matter</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-15836190.post-113676668648908368</id><published>2006-01-08T15:55:00.000-08:00</published><updated>2006-01-09T11:50:44.863-08:00</updated><title type='text'>c++ -- constructor / destructor in inheritacne</title><content type='html'>Constructors are not inherited. Base class has a constructor taking certain parameters does not mean that derived class will have this automatically.  But constructors in parent class does impact the behaviors of derived classes. Each constructor in derived classes must call some constructor from its parent class.  Each destructor in derived classes will automatically call destrctors from the parent class.&lt;br /&gt;&lt;br /&gt;If you do not have any constructors defined, C++ will create a default constructor for you. But once you define a constructor, C++ compile will not give you the default constructor any more.&lt;br /&gt;&lt;br /&gt;Default constructors are always called first in derived classes' contructors except for that you explicitly call a non-default constructor of the parent class.&lt;br /&gt;&lt;br /&gt;If you defined a non-default contructor in your parent class and you did not define a default contructor, in your derived class, your constructor must explicitly call a constructor from the parent class. Otherwise, it will try to call default constructor and wont find it.&lt;br /&gt;&lt;br /&gt;You can call a constructor in the parent like this:&lt;br /&gt;&lt;br /&gt;class A : public B&lt;br /&gt;{&lt;br /&gt;   A(int i) : B(i)&lt;br /&gt;   {};&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;Destructors are called always by derived classes's destructors.  Just derived class's destructors are called first.&lt;br /&gt;&lt;br /&gt;For constructors, C# inherits the same concept except for that when it call base constructors it does not go by name but use the keyword - "base".&lt;br /&gt;&lt;br /&gt;Destructors is a totally different story in C# because of gabbage collection.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/15836190-113676668648908368?l=forthosewhomatters.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://forthosewhomatters.blogspot.com/feeds/113676668648908368/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=15836190&amp;postID=113676668648908368' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/15836190/posts/default/113676668648908368'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/15836190/posts/default/113676668648908368'/><link rel='alternate' type='text/html' href='http://forthosewhomatters.blogspot.com/2006/01/c-constructor-destructor-in.html' title='c++ -- constructor / destructor in inheritacne'/><author><name>For Those Who Matter</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-15836190.post-113674251982901008</id><published>2006-01-08T09:04:00.000-08:00</published><updated>2006-01-09T13:42:57.116-08:00</updated><title type='text'>Inheritance - from C++ to C#</title><content type='html'>Inheritance is a mechanism through which a subclass inherits the properties and behavior of its superclass.&lt;br /&gt;&lt;br /&gt;Inheritance can be public, protected and private. Defalut inheritance is private. Developer can redeclare the "privated" members to public in derived class if that does not violate the encapsulation rule.&lt;br /&gt;&lt;br /&gt;C++ allow multiple inheritance. It could easily cause ambiguities. One of the is caused by deriving from two classes that have same common base class. Your program might have two copies of the base class. To solve this ambiguity, C++ introduces virtual base class. On other words, you use the key word "virtual" when you inherit from base class.&lt;br /&gt;&lt;br /&gt;Aother ambiguty caused by multiple inheritance is that parent classes may have same member names. When you program calls this function through the derived class, you have to point out from which parent you want the function from.&lt;br /&gt;&lt;br /&gt;In addition to multiple inheritance, single inheritance could cause ambiguity also. Derived class could have a member function name the same as the one in its parent.&lt;br /&gt;&lt;br /&gt;class A&lt;br /&gt;{&lt;br /&gt;public:&lt;br /&gt;void foo()&lt;br /&gt;{&lt;br /&gt;cout &lt;&lt; "A::foo"; } } class B : public class A { public: void foo() { cout &lt;&lt; "B::foo"; } } A* a = new B; A* a = new A; b-&gt;foo(); C++ will simply call the foo function in base class. If you want to execute the function according to the real type of the instance, you have to use late binding that you declare the function as virtual in your base class.&lt;br /&gt;&lt;br /&gt;C# gets rid of multiple inheritance. It introducts a new concept "interface". All members in interface is default to public and have to be public and without implementation. A class can implement more than one interfaces but can only inherit one parent class. This has eliminated lots of ambiguities but not all of them. For example, two interfaces could have mebers having the same name. Then, if you program implements those interfaces at the same time, you have to explicitly use the complete name. When you use this member, you have to convert the reference the related interface.&lt;br /&gt;&lt;br /&gt;C# has only public inheritance.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/15836190-113674251982901008?l=forthosewhomatters.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://forthosewhomatters.blogspot.com/feeds/113674251982901008/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=15836190&amp;postID=113674251982901008' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/15836190/posts/default/113674251982901008'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/15836190/posts/default/113674251982901008'/><link rel='alternate' type='text/html' href='http://forthosewhomatters.blogspot.com/2006/01/inheritance-from-c-to-c.html' title='Inheritance - from C++ to C#'/><author><name>For Those Who Matter</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-15836190.post-113669540083420806</id><published>2006-01-07T20:31:00.000-08:00</published><updated>2006-01-07T20:43:23.510-08:00</updated><title type='text'>c/c++ Pointers vs References</title><content type='html'>Both pointers and References are used to hold memory addresses.  There are three main differences:&lt;br /&gt;&lt;br /&gt;1. Reference has to be initialized when you declare a reference variable. It must point to some variable.  &lt;br /&gt;&lt;br /&gt;2. Deference a pointer and reference are different.&lt;br /&gt;For pinters, use *pt = 2;&lt;br /&gt;For refences, directly use ref = 2;&lt;br /&gt;&lt;br /&gt;3. Pointers can be involved in address calculation while reference can not.&lt;br /&gt;&lt;br /&gt;In addition,  reference is used often in operators overloading.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/15836190-113669540083420806?l=forthosewhomatters.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://forthosewhomatters.blogspot.com/feeds/113669540083420806/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=15836190&amp;postID=113669540083420806' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/15836190/posts/default/113669540083420806'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/15836190/posts/default/113669540083420806'/><link rel='alternate' type='text/html' href='http://forthosewhomatters.blogspot.com/2006/01/cc-pointers-vs-references.html' title='c/c++ Pointers vs References'/><author><name>For Those Who Matter</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-15836190.post-113668296650079224</id><published>2006-01-07T16:13:00.000-08:00</published><updated>2006-01-08T08:57:14.580-08:00</updated><title type='text'>Casting operators in C++ and C#</title><content type='html'>C++ support C style cast. It is also called explicitly cast. For example,&lt;br /&gt;&lt;br /&gt;double d = 1.2;&lt;br /&gt;int i = (int)d;&lt;br /&gt;&lt;br /&gt;In the above case implicitly cast is not allowed by compiler because covert a double to int will lose information.&lt;br /&gt;&lt;br /&gt;We treat the above explicitly casting operation as traditional explicit cast. It allows to to convert one type to any other type. And thus, if there is illegal cast, it depends on the run time to either return an error or throw out an exception. Sometimes, it could make the program in an undetermistic state.&lt;br /&gt;&lt;br /&gt;To improve the cast opertion, C++ introduces for more cast operators:&lt;br /&gt;&lt;br /&gt;reintepret_cast&lt;new&gt;(expression), it acts just like triditional explicit cast. Thus it is not safe.&lt;br /&gt;&lt;br /&gt;static_cast&lt;new&gt;(expression), it casts between pointers that point to related classes, not only from children class to parent class but also from parent class to child class. It does not do run time check. Thus it improves performances comparing to dynamic_cast. But it is not safe and could leads to erros.&lt;br /&gt;&lt;br /&gt;dynamic_cast&lt;new&gt;(expression), just like static_cast, dynamic_cast casts pointers of related classes. But dynmaic_cast done run time checking, if a type mismatch is found, it will return a null. This is safer though it increases a little overhead. And dynamic cast can only cast pointers or references not like static_cast can cast numeric types also.&lt;br /&gt;&lt;br /&gt;const_cast&lt;new&gt;(expression), const_cast can remove const, volatile and _unaligned from types.&lt;br /&gt;&lt;br /&gt;#include &lt;iostream.h&gt;&lt;br /&gt;class CCTest&lt;br /&gt;{&lt;br /&gt;public:&lt;br /&gt;void setNumber( int );&lt;br /&gt;void printNumber() const;&lt;br /&gt;private:&lt;br /&gt;int number;&lt;br /&gt;};&lt;br /&gt;void CCTest::setNumber( int num )&lt;br /&gt;{ number = num; }&lt;br /&gt;&lt;br /&gt;void CCTest::printNumber() const&lt;br /&gt;{&lt;br /&gt;cout &lt;&lt; "\nBefore: " &lt;&lt;&gt;( this )-&gt;number--;&lt;br /&gt;cout &lt;&lt; "\nAfter: " &lt;&lt; number;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;void main()&lt;br /&gt;{&lt;br /&gt;CCTest X;&lt;br /&gt;X.setNumber( 8 );&lt;br /&gt;X.printNumber();&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;C# is back to trditional casting, but it does not allow unrelated types casting.  C# also introduce a new key work "as".  If an cast can not be done, it returns a null. If we use explicit casting, we will get a run time exception at this case. C# also supplies a way of converting between value types and reference types called - boxing.&lt;br /&gt;&lt;br /&gt;We can see that C# gives up arbitary casting and constant casting. From this, we can also see C# designers try to eliminate the possibles errors developer could made from language level.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/15836190-113668296650079224?l=forthosewhomatters.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://forthosewhomatters.blogspot.com/feeds/113668296650079224/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=15836190&amp;postID=113668296650079224' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/15836190/posts/default/113668296650079224'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/15836190/posts/default/113668296650079224'/><link rel='alternate' type='text/html' href='http://forthosewhomatters.blogspot.com/2006/01/casting-operators-in-c-and-c.html' title='Casting operators in C++ and C#'/><author><name>For Those Who Matter</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-15836190.post-113658408054375817</id><published>2006-01-06T12:57:00.000-08:00</published><updated>2006-01-06T13:53:48.566-08:00</updated><title type='text'>"Case statement" - what has changed from C++ to C#</title><content type='html'>Case statement has changed a little bit in C# than in C++.&lt;br /&gt;&lt;br /&gt;The jump-statement is required after each block, including the last block whether it is a case statement or a default statement. Unlike the C++ switch statement, C# does not support an explicit fall through from one case label to another. If you want, you can use goto a switch-case, or goto default.&lt;br /&gt;&lt;br /&gt;switch(n)&lt;br /&gt;{&lt;br /&gt;case 1:&lt;br /&gt;cost += 25;&lt;br /&gt;break;&lt;br /&gt;case 2:&lt;br /&gt;cost += 25;&lt;br /&gt;goto case 1;&lt;br /&gt;case 3:&lt;br /&gt;cost += 50;&lt;br /&gt;goto case 1;&lt;br /&gt;default:&lt;br /&gt;Console.WriteLine("Invalid selection. Please select 1, 2, or 3.");&lt;br /&gt;break;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;Although fall through from one case label to another is not supported, it is allowed to stack case labels, for example:&lt;br /&gt;case 0:&lt;br /&gt;case 1:&lt;br /&gt;// do something;&lt;br /&gt;&lt;br /&gt;Then, why does c# act like this?&lt;br /&gt;&lt;br /&gt;We know, on one hand, C++ is very flexible, it enables developer do lots of stuff, on the other hand, this creates some ambiguities and possible security problems. When designing C#, MS tried to ensure developers know what they are doing. For example, you can not override a method without the key word "override" and override is only associated with virtual functions. If a function is not virtual, you can not override it, instead, if developers really want to introduce new implementation, they have to use the key word "new".&lt;br /&gt;&lt;br /&gt;We can see the "Clear Intention" principle in the language designing process. Bear this in mind, in the case statement case, we can see that c# is actually require developers clearly define what they want to go after the last statement in each case block. And applying this to the emplty case block senario, c# knows that if a developer intentionally leave a case block blank, clearly, the developer want sth, and it enables them to fall through to next case statement.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/15836190-113658408054375817?l=forthosewhomatters.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://forthosewhomatters.blogspot.com/feeds/113658408054375817/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=15836190&amp;postID=113658408054375817' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/15836190/posts/default/113658408054375817'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/15836190/posts/default/113658408054375817'/><link rel='alternate' type='text/html' href='http://forthosewhomatters.blogspot.com/2006/01/case-statement-what-has-changed-from-c.html' title='&quot;Case statement&quot; - what has changed from C++ to C#'/><author><name>For Those Who Matter</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-15836190.post-113650417141551405</id><published>2006-01-05T15:29:00.000-08:00</published><updated>2006-01-05T15:36:11.430-08:00</updated><title type='text'>DataSet, DataReader and DataRelation</title><content type='html'>DataReader is connected, forward-only, read-only.&lt;br /&gt;&lt;br /&gt;DataSet uses SqlDataAdapter as a bridge between the connected and disconnected objects.DataSet can read and load itself from an XML document as well as export its rowset to an XML document.&lt;br /&gt;&lt;br /&gt;DataRelation represents a parent/child relationship between two DataTable objects.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/15836190-113650417141551405?l=forthosewhomatters.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://forthosewhomatters.blogspot.com/feeds/113650417141551405/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=15836190&amp;postID=113650417141551405' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/15836190/posts/default/113650417141551405'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/15836190/posts/default/113650417141551405'/><link rel='alternate' type='text/html' href='http://forthosewhomatters.blogspot.com/2006/01/dataset-datareader-and-datarelation.html' title='DataSet, DataReader and DataRelation'/><author><name>For Those Who Matter</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-15836190.post-113638914227465810</id><published>2006-01-04T07:36:00.000-08:00</published><updated>2006-01-04T07:39:02.306-08:00</updated><title type='text'>string and wstring</title><content type='html'>Both string and wstring are created from a common template class called basic_string. wstring class is designed to support international character sets.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/15836190-113638914227465810?l=forthosewhomatters.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://forthosewhomatters.blogspot.com/feeds/113638914227465810/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=15836190&amp;postID=113638914227465810' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/15836190/posts/default/113638914227465810'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/15836190/posts/default/113638914227465810'/><link rel='alternate' type='text/html' href='http://forthosewhomatters.blogspot.com/2006/01/string-and-wstring.html' title='string and wstring'/><author><name>For Those Who Matter</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-15836190.post-113500795063085750</id><published>2005-12-19T07:51:00.000-08:00</published><updated>2005-12-19T07:59:10.650-08:00</updated><title type='text'>Why does the wireless network ask for a WEP key?</title><content type='html'>You are try to connect your computer to a wireless network, but you can not get it because it asks you for a WEP key.&lt;br /&gt;&lt;br /&gt;So, what is the WEP key?&lt;br /&gt;&lt;br /&gt;WEP (wired equivalent privacy) is 802.11's optional encryption standard implemented in the MAC Layer that most radio network interface card (NIC) and access point vendors support. If a user activates WEP, the NIC encrypts the payload (frame body and CRC) of each 802.11 frame before transmission using an RC4 stream cipher provided by RSA Security. The receiving station, such as an access point or another radio NIC, performs decryption upon arrival of the frame. As a result, 802.11 WEP only encrypts data between 802.11 stations. &lt;br /&gt;&lt;br /&gt;If a wireless is activating WEP, it will keep your computer out if you do not know the right WEP key.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/15836190-113500795063085750?l=forthosewhomatters.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://forthosewhomatters.blogspot.com/feeds/113500795063085750/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=15836190&amp;postID=113500795063085750' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/15836190/posts/default/113500795063085750'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/15836190/posts/default/113500795063085750'/><link rel='alternate' type='text/html' href='http://forthosewhomatters.blogspot.com/2005/12/why-does-wireless-network-ask-for-wep.html' title='Why does the wireless network ask for a WEP key?'/><author><name>For Those Who Matter</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-15836190.post-113459567056319053</id><published>2005-12-14T12:56:00.000-08:00</published><updated>2005-12-14T13:27:50.600-08:00</updated><title type='text'>Several valuable aspects from practice for coding</title><content type='html'>1. Design&lt;br /&gt;&lt;br /&gt;Design is always the first concern when coding.  A good design should be less hard coding. A good design should be flexible. You should always think about questions like: what if there are changes, what if there are more functions to add, what if people want to reuse the piece you are writing......&lt;br /&gt;&lt;br /&gt;2. Readability&lt;br /&gt;&lt;br /&gt;Codes should be easily understoodable at least by your peer developers. You should always think, is the logic too tricky, are the names straightforward, are the names consistent with other codes......&lt;br /&gt;&lt;br /&gt;3. Efficiency&lt;br /&gt;&lt;br /&gt;Performance has to be a concern. Do you the big O of your implementation, is there something your can not tell in the codes, what if the load is huge...&lt;br /&gt;&lt;br /&gt;4. Exception Handling&lt;br /&gt;&lt;br /&gt;Codes have to handle exception nicely.  "NULL" exception is the most frequently seen one.  When ever you write  come function or call some function with parameters, you have to think about, what if the parameter is null. Whereever there is a possibility of such thing,  just do a condition checking.  If there is something you are really not sure and can not do condition check easily, just use try and catch to handle it.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/15836190-113459567056319053?l=forthosewhomatters.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://forthosewhomatters.blogspot.com/feeds/113459567056319053/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=15836190&amp;postID=113459567056319053' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/15836190/posts/default/113459567056319053'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/15836190/posts/default/113459567056319053'/><link rel='alternate' type='text/html' href='http://forthosewhomatters.blogspot.com/2005/12/several-valuable-aspects-from-practice.html' title='Several valuable aspects from practice for coding'/><author><name>For Those Who Matter</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-15836190.post-113416254546348161</id><published>2005-12-09T13:08:00.000-08:00</published><updated>2005-12-09T13:09:05.483-08:00</updated><title type='text'>Some findings and Discussions about Moving From Crystal 9 to Crystal XI</title><content type='html'>In the past couple of days, I've been evaluating Crystal XI with the following questions in my mind:&lt;br /&gt;1) Does Crystal XI really have feature of "exporting reports to editable word documents"? If yes, how does it work?&lt;br /&gt;2) Will our current crystal reports in IPlanner automatically work in the new Crystal XI environment?&lt;br /&gt;3) Will our current crystal reports in Institution Equity automatically work in the new Crystal XI environment?&lt;br /&gt;4) What have to be done to make our current Crystal reports work in Crystal XI environment?&lt;br /&gt;5) Will the current reports still look the same in Crystal XI?&lt;br /&gt;6) Can we develop reports in Crystal 9 now and lately run them in Crystal XI?&lt;br /&gt;I did the evaluation in three ways: gooogling the internet, making some phone calls to Business Objects and most importantly testing and verifying the finding on the machine - iiss30ny1us12 where we've set up Crystal XI.&lt;br /&gt;Here's What I find out. I will just go through them question by question.&lt;br /&gt;1) Does Crystal XI really have feature of "exporting reports to editable word documents"? If yes, how does it work?&lt;br /&gt;Crystal XI does start supporting making the exported reports editable in RTF format. This feature is very easy to use. It is just one more choice that you can make when you export the reports. However, editable RTF format right now have some limitations. One noticed thing is that editable RTF format can not contain lines and boxes in it. This has been confirmed from the supporting staff of Business Objects.&lt;br /&gt;2) Will our current crystal reports from IPlanner automatically work in the new Crystal XI environment?&lt;br /&gt;Crystal reports in IPlanner are written with Crystal managed APIs. The managed APIs are tied to version numbers. So the current reports won't automatically work in Crystal XI. However, ASP.NET allow us to redirect the dll dependency to difference versions. So, we can change the web.config file to redirect requests for Crystal 9 to Crystal 11. I tested the solution on iiss30ny1us12. It worked fine. But this is not all. One thing I noticed is that I have to tie the dataset schema to a file instead of a class from a project. This might be related to that the MS Visual Studio we are using now is not integrated with Crystal XI.&lt;br /&gt;3) Will our current crystal reports from Institution Equity automatically work in the new Crystal XI environment?&lt;br /&gt;The crystal reports in Institution Equity are delivered in an unmanaged way. This is no longer supported in Crystal XI (For more details about this, please reference the article (1)). Although those rpt files might be still useful, we have to find a managed way to deliver them in Crystal XI.&lt;br /&gt;4) What have to be done to make our current Crystal reports work in Crystal XI environment?&lt;br /&gt;This has been discussed in the above.&lt;br /&gt;5) Will the current reports still look the same in Crystal XI?&lt;br /&gt;Other than the editable RTF format, I compared a couple of reports in IPlanner generated with CR 9 and CR XI, I did not find any difference.&lt;br /&gt;6) Can we develop reports in Crystal 9 now and lately run them on Crystal XI?&lt;br /&gt;Yes, if we develop the reports by using managed API. But still there needs some extra steps that I mentioned in the discussion to question 2.&lt;br /&gt;&lt;br /&gt;Some interesting links:&lt;br /&gt;(1) Is URL reporting supported in Crystal Enterprise?, http://support.businessobjects.com/library/kbase/articles/c2016644.asp.&lt;br /&gt;(2) Crystal Reports XI Feature Comparison by Version and Edition, http://www.businessobjects.com/pdf/products/crystalreports/crxi_feat_ver_ed.pdf&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/15836190-113416254546348161?l=forthosewhomatters.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://forthosewhomatters.blogspot.com/feeds/113416254546348161/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=15836190&amp;postID=113416254546348161' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/15836190/posts/default/113416254546348161'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/15836190/posts/default/113416254546348161'/><link rel='alternate' type='text/html' href='http://forthosewhomatters.blogspot.com/2005/12/some-findings-and-discussions-about.html' title='Some findings and Discussions about Moving From Crystal 9 to Crystal XI'/><author><name>For Those Who Matter</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-15836190.post-113407251620950186</id><published>2005-12-08T12:05:00.000-08:00</published><updated>2005-12-08T12:08:36.210-08:00</updated><title type='text'>Issues and Solutions Related to Converting ASP.NET 1.x to ASP.NET2.0</title><content type='html'>&lt;a href="http://msdn.microsoft.com/asp.net/default.aspx?pull=/library/en-us/dnaspp/html/conversionissuesasp_net.asp"&gt;&lt;br /&gt;Common Web Project Conversion Issues and Solutions &lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/15836190-113407251620950186?l=forthosewhomatters.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://forthosewhomatters.blogspot.com/feeds/113407251620950186/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=15836190&amp;postID=113407251620950186' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/15836190/posts/default/113407251620950186'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/15836190/posts/default/113407251620950186'/><link rel='alternate' type='text/html' href='http://forthosewhomatters.blogspot.com/2005/12/issues-and-solutions-related-to.html' title='Issues and Solutions Related to Converting ASP.NET 1.x to ASP.NET2.0'/><author><name>For Those Who Matter</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-15836190.post-113397390831473180</id><published>2005-12-07T08:36:00.000-08:00</published><updated>2005-12-07T08:51:26.416-08:00</updated><title type='text'>change the dependency of a .Net assembly</title><content type='html'>If an assembly references to other assemblies, those assemblies become dependencies of the assembly. These depenencies are written inside the meta data that are inserted when you build the assembly. &lt;br /&gt;&lt;br /&gt;Those dependencies can be strong named asseblies. For a web application, you can change the dependencies between versions. &lt;br /&gt;&lt;br /&gt;Here's what you have to do:&lt;br /&gt;&lt;br /&gt;&lt; runtime &gt;&lt;br /&gt;      &lt; assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1"&gt;&lt;br /&gt;         &lt; dependentAssembly &gt;&lt;br /&gt;            &lt; assemblyIdentity name="CrystalDecisions.CrystalReports.Engine"&lt;br /&gt;                              publicKeyToken="692fbea5521e1304"&lt;br /&gt;                              culture="neutral" /&gt;&lt;br /&gt;            &lt; bindingRedirect oldVersion="9.2.3300.0"&lt;br /&gt;                             newVersion="11.0.3300.0"/&gt;&lt;br /&gt;        &lt;/dependentAssembly&gt;&lt;br /&gt;       &lt;/assemblyBinding&gt;&lt;br /&gt;&lt;/runtime&gt;&lt;br /&gt;&lt;br /&gt;Put this piece of instruction inside the web.config file, you can change the depencies between versions at runtime.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/15836190-113397390831473180?l=forthosewhomatters.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://forthosewhomatters.blogspot.com/feeds/113397390831473180/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=15836190&amp;postID=113397390831473180' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/15836190/posts/default/113397390831473180'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/15836190/posts/default/113397390831473180'/><link rel='alternate' type='text/html' href='http://forthosewhomatters.blogspot.com/2005/12/change-dependency-of-net-assembly.html' title='change the dependency of a .Net assembly'/><author><name>For Those Who Matter</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-15836190.post-113380043980058819</id><published>2005-12-05T08:18:00.000-08:00</published><updated>2005-12-05T08:33:59.900-08:00</updated><title type='text'>Design Pattern - One reason you better use a simple factory</title><content type='html'>Sometimes for a little bit comlicated field in an object, you are not parameterize this field directly and in fact you need caculate from other fields and even more outside information. From time to time, you may need add such a field into your existed class. A simple way to add this would be:&lt;br /&gt;&lt;br /&gt;YourClass yc = new YourClass();&lt;br /&gt;yc.newField = Calculate();&lt;br /&gt;......&lt;br /&gt;&lt;br /&gt;The bad part about this method is that you have to add the line - yc.newField = Calculate() everywhere in your code where you have "new YourClass()". And in the future if you ever need add another such field, you need do this again. This is problematic, it is can cause some bug because it is very possible that you will miss one or places where you should do this.&lt;br /&gt;&lt;br /&gt;Therefore, we should use the better way  - A simple factory. &lt;br /&gt;&lt;br /&gt;YourClass CreateYourClass()&lt;br /&gt;{&lt;br /&gt;  YourClass yc = new YourClass();&lt;br /&gt;  yc.newField = Calculate();&lt;br /&gt;  ......&lt;br /&gt;  return yc;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;So if the client always use this method to generate instance, any time when you need add a new field,  the client will automatically have it. &lt;br /&gt;&lt;br /&gt;This sample should remind us that we better not create instances in the "hard code" way, instead, let's use factory.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/15836190-113380043980058819?l=forthosewhomatters.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://forthosewhomatters.blogspot.com/feeds/113380043980058819/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=15836190&amp;postID=113380043980058819' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/15836190/posts/default/113380043980058819'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/15836190/posts/default/113380043980058819'/><link rel='alternate' type='text/html' href='http://forthosewhomatters.blogspot.com/2005/12/design-pattern-one-reason-you-better.html' title='Design Pattern - One reason you better use a simple factory'/><author><name>For Those Who Matter</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-15836190.post-113355674505773593</id><published>2005-12-02T09:29:00.000-08:00</published><updated>2005-12-06T11:29:14.916-08:00</updated><title type='text'>Immigrate From Crystal 9 to Crystal 11</title><content type='html'>We have two ways of using Crystal Report.&lt;br /&gt;&lt;br /&gt;One is through CR integrated into .NET platform.&lt;br /&gt;&lt;br /&gt;Here's the link I found that has feature comparison among different versions.&lt;br /&gt;&lt;br /&gt;http://www.businessobjects.com/pdf/products/crystalreports/crxi_feat_ver_ed.pdf&lt;br /&gt;&lt;br /&gt;My plan is to install the whole application on one machine, and then with the Crystal 11 already installed, we can test whether the current crystal report that is written in CR 9 still works fine in CR 11 environment.&lt;br /&gt;&lt;br /&gt;Plan changed. Obviouse, CR9 report can not automatically run in CR11 environment. This is caused by "side by side" execution. So we change the dependency of current web application and instruct the web application to user CR11 instead of CR9.&lt;br /&gt;&lt;br /&gt;This is the right step, but not the last step. CR11 has difficulty to find dataset which is previously put in web dll. So We told CR to use physically XSD file instead of the one in the dll. This fixed lots of problems.&lt;br /&gt;&lt;br /&gt;Then another slight issue is to switch CR's own web documents.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/15836190-113355674505773593?l=forthosewhomatters.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://forthosewhomatters.blogspot.com/feeds/113355674505773593/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=15836190&amp;postID=113355674505773593' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/15836190/posts/default/113355674505773593'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/15836190/posts/default/113355674505773593'/><link rel='alternate' type='text/html' href='http://forthosewhomatters.blogspot.com/2005/12/immigrate-from-crystal-9-to-crystal-11.html' title='Immigrate From Crystal 9 to Crystal 11'/><author><name>For Those Who Matter</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-15836190.post-113340866749340182</id><published>2005-11-30T19:43:00.000-08:00</published><updated>2005-11-30T19:44:27.510-08:00</updated><title type='text'>Frequent used office compliment</title><content type='html'>1.you look great today.（你今天看上去很棒。）【每天都可以用！】&lt;br /&gt;&lt;br /&gt;2. you did a good job. （你干得非常好。）【国际最通用的表扬！】&lt;br /&gt;&lt;br /&gt;3. we’re so proud of you.（我们十分为你骄傲。）【最高级的表扬！】&lt;br /&gt;&lt;br /&gt;4. i’m very pleased with your work.（我对你的工作非常满意。）【正式、真诚的赞扬！】&lt;br /&gt;&lt;br /&gt;5. this is really a nice place.（这真是个好地方！）【随口就说、但效果很好的表扬！】&lt;br /&gt;&lt;br /&gt;6. you’re looking sharp!（你看上去真精神/真棒/真漂亮。）【与众不同的表扬！】&lt;br /&gt;&lt;br /&gt;7. you always know the right thing to say.&lt;br /&gt;&lt;br /&gt;= 8. you’re very eloquent.（你总是说话得体。）【高层次的表扬！】&lt;br /&gt;&lt;br /&gt;9. nice going! = you did a good job.（干得好！）【极其地道的表扬！】&lt;br /&gt;&lt;br /&gt;10. the food is delicious.（好吃！）【最普通、但非常重要的表扬！】&lt;br /&gt;&lt;br /&gt;11. everything tastes great.（每样东西都很美味！）&lt;br /&gt;&lt;br /&gt;12. your son/daughter is so cute.（你的孩子很可爱。）【外国人绝对喜欢听的表扬！】&lt;br /&gt;&lt;br /&gt;13. what an adorable baby!（多么可爱的孩子。）【只管大胆用！】&lt;br /&gt;&lt;br /&gt;14. i admire your work.&lt;br /&gt;&lt;br /&gt;= 15. i respect your work.（我对你的工作表示敬意。）【世界通用！】&lt;br /&gt;&lt;br /&gt;16. you’ve got a great personality.（你的个性很好。）【一个非常安全的表扬！】&lt;br /&gt;&lt;br /&gt;17. you have a good sense of humor.（你真幽默。）【美国人极其喜欢的表扬！】&lt;br /&gt;&lt;br /&gt;18. your chinese is really surprising.（你的中文令人惊讶。）【绝对和其他人不一样的表扬！】&lt;br /&gt;&lt;br /&gt;19. your english is incredible.（我真不敢相信你的英语。）【用了六星级形容词！】&lt;br /&gt;&lt;br /&gt;20. you have a very successful business.（你的事业很成功。）【现代人非常喜欢听！】&lt;br /&gt;&lt;br /&gt;21. you’re very professional.（你非常专业。）【专业化的表扬！】&lt;br /&gt;&lt;br /&gt;22. your company is very impressive.（你的公司给我留下深刻印象。）&lt;br /&gt;&lt;br /&gt;23. you’re so smart.（你非常聪明。）&lt;br /&gt;&lt;br /&gt;24. i envy you very much.（我非常羡慕你。）&lt;br /&gt;&lt;br /&gt;25. your wife is very charming.（你的妻子很有魅力！）&lt;br /&gt;&lt;br /&gt;26. you two make a lovely couple.（你们真是天生的一对！）&lt;br /&gt;&lt;br /&gt;27. you’re really talented.（你很有天赋。）&lt;br /&gt;&lt;br /&gt;28. you look nice in that color.（你穿那种颜色很好看。）&lt;br /&gt;&lt;br /&gt;29. you have a good taste.（你很有品位。）&lt;br /&gt;&lt;br /&gt;30. you look like a million dollars. = you look outstanding.=you look like a movie star.（你看上去帅呆了。）&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/15836190-113340866749340182?l=forthosewhomatters.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://forthosewhomatters.blogspot.com/feeds/113340866749340182/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=15836190&amp;postID=113340866749340182' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/15836190/posts/default/113340866749340182'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/15836190/posts/default/113340866749340182'/><link rel='alternate' type='text/html' href='http://forthosewhomatters.blogspot.com/2005/11/frequent-used-office-compliment.html' title='Frequent used office compliment'/><author><name>For Those Who Matter</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-15836190.post-113088746557104169</id><published>2005-11-01T15:11:00.000-08:00</published><updated>2005-11-01T15:24:25.600-08:00</updated><title type='text'>Distributed computing is so easy with .Net Web Service</title><content type='html'>Web Service in .Net is very easy to implement. It is a convenient way to provide functions and data to remote clients. And best of all, it is platform neutrol. You can use web service written in any language provided by any platform.&lt;br /&gt;&lt;br /&gt;In .Net, to implement a web Service, you just need add an web service file (.asmx) into your web project. Then, you implement your methods with the attribute [WebMethod]. These methods will be available for remote clients.&lt;br /&gt;&lt;br /&gt;For a client to consume web serice, in .Net it is very simple also. .Net provides a tool named wsdl.exe. You just need give the URI of a certain web service, the tool will generate a proxy locally for you to use. In your client, you use the proxy to create an instance of the web service, then you can call and method the web service provides.&lt;br /&gt;&lt;br /&gt;Web Service is Cool!!!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/15836190-113088746557104169?l=forthosewhomatters.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://forthosewhomatters.blogspot.com/feeds/113088746557104169/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=15836190&amp;postID=113088746557104169' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/15836190/posts/default/113088746557104169'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/15836190/posts/default/113088746557104169'/><link rel='alternate' type='text/html' href='http://forthosewhomatters.blogspot.com/2005/11/distributed-computing-is-so-easy-with.html' title='Distributed computing is so easy with .Net Web Service'/><author><name>For Those Who Matter</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-15836190.post-113087460541975487</id><published>2005-11-01T11:31:00.000-08:00</published><updated>2005-11-01T11:50:05.453-08:00</updated><title type='text'>The secret of crytal CUT-OFF</title><content type='html'>Crystal sucks! Yes. It does! When it exports one report to MS Word format, it creates lots of problems. One of them is some of last line text gets cut-off.&lt;br /&gt;&lt;br /&gt;Today, I believe I find the secret - the cause for this incident. When crystal exports its report document to MS Word format, it packs text into a series of text boxes. The sizes of the text boxes are procalculated and thus are fixed. Crystal does calculations based on the size of the text. However, MS seems to require some space pad in the right of box - there has to be some space between the text and the right border of the text box. And if a line of text is too long for the text box, it will wrap by MS to next line. But crystal does not seem to know this. So it calculates the height of box wrong at time when there is an exact wrap up - Cystal thinks there is space for a word in one line, but MS does not think so.&lt;br /&gt;&lt;br /&gt;To solve this problem, I tried to pad an extra char at the end of the text. It works for right now.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/15836190-113087460541975487?l=forthosewhomatters.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://forthosewhomatters.blogspot.com/feeds/113087460541975487/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=15836190&amp;postID=113087460541975487' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/15836190/posts/default/113087460541975487'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/15836190/posts/default/113087460541975487'/><link rel='alternate' type='text/html' href='http://forthosewhomatters.blogspot.com/2005/11/secret-of-crytal-cut-off.html' title='The secret of crytal CUT-OFF'/><author><name>For Those Who Matter</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-15836190.post-113079901758822159</id><published>2005-10-31T14:23:00.000-08:00</published><updated>2005-11-21T10:53:44.613-08:00</updated><title type='text'>Two new interesting features in ASP .NET 2.0</title><content type='html'>ASP .NET 2.0 has introduced quite a few new features. Two of the interesting and very useful ones are: dynamically compiled classes and simplified code behind pages.&lt;br /&gt;&lt;br /&gt;In ASP .NET 1.0 pre-compiled classes are either put in the BIN directory or in the GAC. This sometimes is very inconvenient for maintaining. For example, if you just need to fix a small thing in one code behind page, you have to rebuild the whole assembly to do a HOT FIX. This could bring undesired result to production environment because of reckless developers. Now, in ASP .NET 2.0, this is can be solved. It allows you to place shared class file sources in the App_Code directory, where they will be dynamically compiled just as ASPX pages. Thus, you can put frequently changing source classes here. So you don't have to rebuild the whole assembly when you have to do HOT FIXES.&lt;br /&gt;&lt;br /&gt;Simplified code behind pages is also very convenient. In ASP .NET 1.0, aspx page is inherited from the class defined in code behind. So to access the controls defined in ASPX file, the code behind has to redefined it. If you have more than 15 controls, it will be very inconvenient. In ASP .NET 2.0, a new language feature called partial classes is used. The feature helps to make aspx and its code behind in one class when compiling. Now, you don't have to redefine controls in the aspx files.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/15836190-113079901758822159?l=forthosewhomatters.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://forthosewhomatters.blogspot.com/feeds/113079901758822159/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=15836190&amp;postID=113079901758822159' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/15836190/posts/default/113079901758822159'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/15836190/posts/default/113079901758822159'/><link rel='alternate' type='text/html' href='http://forthosewhomatters.blogspot.com/2005/10/two-new-interesting-features-in-asp.html' title='Two new interesting features in ASP .NET 2.0'/><author><name>For Those Who Matter</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-15836190.post-113042675381995964</id><published>2005-10-27T07:39:00.000-07:00</published><updated>2005-10-30T11:46:33.216-08:00</updated><title type='text'>Type Safe in C++, C# and Java</title><content type='html'>Type Safe means data are accessed only in the way it allows to. This may be a little bit difficult to understand. Let's say  more.&lt;br /&gt;&lt;br /&gt;In OO language, encapsulation is one of the basic principle. Under this principle, data and the methods which are used to modify and access them are meld up together to form a type. Access modifiers such as "public, protected, private, internal, default, package and friend" are used to define who can or can not access the data. Data fields within a type are usually defined as private, that is, only members within the type can access them. By this, the outside of type can only access or modify the fields through publicly available interface. Therefore, the data fields can not randomly manipulated by outsiders, they can only be access and modify in certain ways that whose container defines.  If these rules can be compromised, then the language is not type safe.&lt;br /&gt;&lt;br /&gt;C++ is not type safe. This is mainly caused by that it gives developers so big powers to manipulate pointers. Look at the following example:&lt;br /&gt;&lt;br /&gt;#include &lt;iostream&gt;&lt;br /&gt;using namespace std;&lt;br /&gt;&lt;br /&gt;class A&lt;br /&gt;{&lt;br /&gt;private:&lt;br /&gt; int i;&lt;br /&gt;public:&lt;br /&gt; A(){i=0;}&lt;br /&gt; void Add_1(){i++;}&lt;br /&gt; int Get_i()&lt;br /&gt; {&lt;br /&gt;  return i;&lt;br /&gt; }&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;class B&lt;br /&gt;{&lt;br /&gt;private:&lt;br /&gt; int i;&lt;br /&gt;public:&lt;br /&gt; B(){i = 0;}&lt;br /&gt; void Add_2()&lt;br /&gt; {&lt;br /&gt;  i += 2;&lt;br /&gt; }&lt;br /&gt; int Get_i()&lt;br /&gt; {&lt;br /&gt;  return i;&lt;br /&gt; }&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;int _tmain(int argc, _TCHAR* argv[])&lt;br /&gt;{&lt;br /&gt; A* a = new A();&lt;br /&gt; B* b = reinterpret_cast&lt;B*&gt;(a);&lt;br /&gt; b-&gt;Add_2();&lt;br /&gt; cout &lt;&lt; a-&gt;Get_i() &lt;&lt; "\n";&lt;br /&gt; char ch;&lt;br /&gt; cin &gt;&gt; ch;&lt;br /&gt; return 0;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;In the example above, integer i is a defined as private in type A. It should be accessed by clients only through the public methods defined in A, which in this case are Add and Get_i in A. However, the client, that is the main method, intentionally convert a pointer of type A's instance to a pointer pointing to an instance of type B. Then it calls B's method Add_2, that changes the value i that is origially defined as private in type A. This totally violates the intention of the designer of type A. Here data fields in type A can not avoid being manipulated by outsiders though it is defined as private. So it is not safe. In other words, C++ in not safe because it allows this happening.&lt;br /&gt;&lt;br /&gt;C# is said to be verified type safe language. Though it will not allow cases like the example above happen. &lt;br /&gt;&lt;br /&gt;Java was intended to be type safe. It does not allow randomly manipulate references. However, developers can find other ways to accomplish type-spoofing (1). Therefore, Java is not really type safe language.&lt;br /&gt;&lt;br /&gt;(1)Vijay Saraswat, Java is not type-safe, http://www.cis.upenn.edu/~bcpierce/courses/629/papers/Saraswat-javabug.html.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/15836190-113042675381995964?l=forthosewhomatters.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://forthosewhomatters.blogspot.com/feeds/113042675381995964/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=15836190&amp;postID=113042675381995964' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/15836190/posts/default/113042675381995964'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/15836190/posts/default/113042675381995964'/><link rel='alternate' type='text/html' href='http://forthosewhomatters.blogspot.com/2005/10/type-safe-in-c-c-and-java.html' title='Type Safe in C++, C# and Java'/><author><name>For Those Who Matter</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-15836190.post-113036358537016459</id><published>2005-10-26T14:43:00.000-07:00</published><updated>2005-10-26T19:37:15.343-07:00</updated><title type='text'>A Comparative Overview of C#</title><content type='html'>In June 2000, Microsoft announced both the .NET platform and a new programming language called C#. C# is a strongly-typed object-oriented language designed to give the optimum blend of simplicity, expressiveness, and performance. The .NET platform is centered around a Common Language Runtime (similar to a JVM) and a set of libraries which can be exploited by a wide variety of languages which are able to work together by all compiling to an intermediate language (IL). C# and .NET are a little symbiotic: some features of C# are there to work well with .NET, and some features of .NET are there to work well with C# (though .NET aims to work well with many languages). This article is mostly concerned with C#, but sometimes it is useful to discuss .NET too. The C# language was built with the hindsight of many languages, but most notably Java and C++. It was co-authored by Anders Hejlsberg (who is famous for the design of the Delphi language), and Scott Wiltamuth.&lt;br /&gt;&lt;p class="heading2"&gt;Contents&lt;/p&gt;&lt;br /&gt;&lt;ol&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="#1"&gt;C# and Java&lt;/a&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="#2"&gt;Properties&lt;/a&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="#3"&gt;Indexers&lt;/a&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="#4"&gt;Delegates&lt;/a&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="#5"&gt;Events&lt;/a&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="#6"&gt;Enums&lt;/a&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="#7"&gt;Collections and the Foreach Statement&lt;/a&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="#8"&gt;Structs&lt;/a&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="#9"&gt;Type Unification&lt;/a&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="#10"&gt;Operator Overloading&lt;/a&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="#11"&gt;Polymorphism&lt;/a&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="#12"&gt;Interfaces&lt;/a&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="#13"&gt;Versioning&lt;/a&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="#14"&gt;Parameter Modifiers&lt;/a&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="#15"&gt;Attributes&lt;/a&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="#16"&gt;Selection Statements&lt;/a&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="#17"&gt;Predefined Types&lt;/a&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="#18"&gt;Field Modifiers&lt;/a&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="#19"&gt;Jump Statements&lt;/a&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="#20"&gt;Assemblies, Namespaces &amp; Access Levels&lt;/a&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="#21"&gt;Pointer Arithmetic&lt;/a&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="#22"&gt;Rectangular Arrays&lt;/a&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="#23"&gt;Constructors and Destructors&lt;/a&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="#24"&gt;Managed Execution Environments&lt;/a&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="#25"&gt;Libraries&lt;/a&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="#26"&gt;Interoperability&lt;/a&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="#27"&gt;Conclusion&lt;/a&gt;&lt;/li&gt;&lt;br /&gt;&lt;/ol&gt;&lt;br /&gt;&lt;p class="heading2"&gt;&lt;a name="1"&gt;&lt;/a&gt;1. C# and Java&lt;/p&gt;&lt;br /&gt;Below is a list of features C# and Java share, which are intended to improve on C++. These features are not the focus of this article, but it is very important to be aware of the similarities.&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;Compiles into machine-independent language-independent code which runs in a &lt;a href="#24"&gt;managed execution environment&lt;/a&gt;.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Garbage Collection coupled with the elimination of pointers (in C# restricted use is permitted within code marked unsafe)&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Powerful reflection capabilities&lt;/li&gt;&lt;br /&gt;&lt;li&gt;No header files, all code scoped to packages or assemblies, no problems declaring one class before another with circular dependencies&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Classes all descend from object and must be allocated on the heap with new keyword&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Thread support by putting a lock on objects when entering code marked as locked/synchronized&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Interfaces, with multiple-inheritance of interfaces, single inheritance of implementations&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Inner classes&lt;/li&gt;&lt;br /&gt;&lt;li&gt;No concept of inheriting a class with a specified access level&lt;/li&gt;&lt;br /&gt;&lt;li&gt;No global functions or constants, everything belongs to a class&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Arrays and strings with lengths built-in and bounds checking&lt;/li&gt;&lt;br /&gt;&lt;li&gt;The "." operator is always used, no more -&gt;, :: operators&lt;/li&gt;&lt;br /&gt;&lt;li&gt;null and boolean/bool are keywords&lt;/li&gt;&lt;br /&gt;&lt;li&gt;All values are initialized before use&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Can't use integers to govern if statements&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Try Blocks can have a finally clause&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;&lt;p class="heading2"&gt;&lt;a name="2"&gt;&lt;/a&gt;2. Properties&lt;/p&gt;&lt;p&gt;Properties will be a familiar concept to Delphi and Visual Basic users. The motivation is for the language to formalize the concept of getter/setter methods, which is an extensively used pattern, particularly in RAD (Rapid Application Development) tools.&lt;/p&gt;&lt;p&gt;This is typical code you might write in Java or C++:&lt;/p&gt; foo.setSize (getSize () + 1);&lt;br /&gt;label.getFont().setBold (true);  The same code you would write like this in C#:  foo.size++;&lt;br /&gt;label.font.bold = true;  The C# code is immediately more readable by those who are using   foo and label. There is similar simplicity when implementing   properties: &lt;p&gt;Java/C++:&lt;/p&gt; public int getSize() {&lt;br /&gt; return size;&lt;br /&gt;}&lt;br /&gt;public void setSize (int value) {&lt;br /&gt; size = value;&lt;br /&gt;}&lt;br /&gt;C#:  public int Size {&lt;br /&gt; get {return size;&lt;br /&gt; }&lt;br /&gt; set {size = value;&lt;br /&gt; }&lt;br /&gt;}  Particularly for read/write properties, C# provides a cleaner way of   handling this concept. The relationship between a get and set method  is inherent in C#, while has to be maintained in Java or C++. There  are many benefits of this approach. It encourages programmers to   think in terms of properties, and whether that property is most   natural as read/write vs read only, or whether it really   shouldn't be a property at all. If you wish to change the name   of your property, you only have one place to look (I've seen   getters and setter several hundred lines away from each other).   Comments only have to be made once, and won't get out of sync   with each other. It is feasible that an IDE could help out here   (and in fact I suggest they do), but one should remember an   essential principle in programming is to try to make abstractions   which model our problem space well. A language which supports   properties will reap the benefits of that better abstraction. &lt;div class="comment"&gt;&lt;p&gt;One possible argument against this being a benefit is that you don't know if you're manipulating a field or a property with this syntax. However, almost all classes with any real complexity designed in Java (and certainly in C#) do not have public fields anyway. Fields typically have a reduced access level (private/protected/default) and are only exposed through getter/setters, which means one may as well have the nicer syntax. It is also totally feasible an IDE could parse the code, highlighting properties with a different color, or provide code completion information indicating if it is a property or not. It should also be noted that if a class is designed well, then a user of that class should only worry about the specification of that class, and not its implementation. Another possible argument is that it is less efficient. As a matter a fact, good compilers can in-line the default getter which merely returns a field, making it just as fast as field. Finally, even if using a field is more efficient that a getter/setter, it is a good thing to be able to change the field to a property later without breaking the source code which relies on the property.&lt;/p&gt;&lt;/div&gt;&lt;p class="heading2"&gt;&lt;a name="3"&gt;&lt;/a&gt;3. Indexers&lt;/p&gt;&lt;p&gt;C# provides indexers allow objects to be treated like arrays, except that like properties, each element is exposed with a get and/or set method.&lt;/p&gt; public class Skyscraper&lt;br /&gt;{&lt;br /&gt;    Story[] stories;&lt;br /&gt;    public Story this [int index] {&lt;br /&gt;         get {&lt;br /&gt;               return stories [index];&lt;br /&gt;         }&lt;br /&gt;         set {&lt;br /&gt;              if (value != null) {&lt;br /&gt;                  stories [index] = value;&lt;br /&gt;              }&lt;br /&gt;         }&lt;br /&gt;    }&lt;br /&gt;    ...&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;Skyscraper empireState = new Skyscraper (...);&lt;br /&gt;empireState [102] = new Story ("The Top One", ...);  4. Delegates &lt;p&gt;A delegate can be thought of as a type-safe object-oriented function pointer, which is able to hold multiple methods rather than just one. Delegates handle problems which would be solved with function pointers in C++, and interfaces in Java. It improves on the function pointer approach by being type safe and being able to hold multiple methods. It improves on the interface approach by allowing the invocation of a method without the need for inner-class adapters or extra code to handle multiple-method invocations. The most important use of delegates is for event handling, which is in the next section (which gives an example of how delegates are used).&lt;/p&gt;&lt;p class="heading2"&gt;&lt;a name="5"&gt;&lt;/a&gt;5. Events&lt;/p&gt;&lt;p&gt;C# provides direct support for events. Although event handling has been a fundamental part of programming since programming began, there has been surprisingly little effort made by most languages to formalize this concept. If you look at how today's mainstream frameworks handle events, we've got examples like Delphi's function pointers (called closures), Java's inner class adaptors, and of course, the Windows API's message system. C# uses delegates along with the event keyword to provide a very clean solution to event handling. I thought the best way to illustrate this was to give an example showing the whole process of declaring, firing, and handling an event:&lt;/p&gt; // The Delegate declaration which defines the signature of methods which can be invoked&lt;br /&gt;public delegate void ScoreChangeEventHandler (int newScore, ref bool cancel);&lt;br /&gt;&lt;br /&gt;// Class which makes the event&lt;br /&gt;public class Game {&lt;br /&gt;    // Note the use of the event keyword&lt;br /&gt;    public event ScoreChangeEventHandler ScoreChange;&lt;br /&gt;&lt;br /&gt;    int score;&lt;br /&gt;&lt;br /&gt; // Score Property&lt;br /&gt;    public int Score {&lt;br /&gt;        get {&lt;br /&gt;            return score;&lt;br /&gt;     }&lt;br /&gt;        set {&lt;br /&gt;            if (score != value) {&lt;br /&gt;                bool cancel = false;&lt;br /&gt;                ScoreChange (value, ref cancel);&lt;br /&gt;                if (! cancel)&lt;br /&gt;                    score = value;&lt;br /&gt;            }&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;// Class which handles the event&lt;br /&gt;public class Referee&lt;br /&gt;{&lt;br /&gt;    public Referee (Game game) {&lt;br /&gt;        // Monitor when a score changes in the game&lt;br /&gt;        game.ScoreChange += new ScoreChangeEventHandler (game_ScoreChange);&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    // Notice how this method signature matches the ScoreChangeEventHandler's signature&lt;br /&gt;    private void game_ScoreChange (int newScore, ref bool cancel) {&lt;br /&gt;        if (newScore &lt; cancel =" true;" game =" new" referee =" new" score =" 70;" score =" 110;"&gt;&lt;p&gt;In the GameTest we make a game, make a referee who monitors the game, then change the game's score to see what the referee does in response to this. With this system, the Game has no knowledge of the Referee at all, and simply lets any class listen and act on changes made to its score. The event keyword hides all the delegate's methods apart from += and -= to classes other than the class it is declared in. These operators allow you to add (and remove) as many event handlers as you want to the event.&lt;/p&gt;&lt;p&gt;You will probably first encounter this system in GUI frameworks, where the Game would be analogous to UI widgets which fire events according to user input, and the referee would be analogous to a form, which would process the events.&lt;/p&gt;&lt;p class="comment"&gt;Delegates were first introduced in Microsoft's Visual J++ also designed by Anders Hejlsberg, and were a cause of much technical and legal dispute between Sun and Microsoft. James Gosling, the man who designed Java made a condescending though humorous comment about Anders Hejlsberg, saying his attachment to Delphi made him "Mr. Method Pointers". After examining the arguments against delegates made by Sun, I believe it would be fair to call Gosling "Mr. Everything's-a-Class". In the last few years of programming "make abstractions which try to model reality well" has been replaced by many people with "Reality is object-oriented, so we should model it with object oriented abstractions".&lt;/p&gt;&lt;p class="comment"&gt;Sun's and Microsoft's arguments for and against delegates can be found at:&lt;/p&gt;&lt;div class="comment"&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://www.Javasoft.com/docs/white/delegates.html"&gt;http://www.Javasoft.com/docs/white/delegates.html&lt;/a&gt;&lt;br /&gt;&lt;a href="http://msdn.microsoft.com/visualj/technical/articles/delegates/truth.asp"&gt;http://msdn.microsoft.com/visualj/technical/articles/delegates/truth.asp&lt;/a&gt;&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;&lt;p&gt;6. Enums&lt;/p&gt;&lt;p&gt;In case you don't know C, Enums let you specify a group of objects, e.g.:&lt;/p&gt;&lt;p&gt;Declaration:&lt;/p&gt; public enum Direction {North, East, West, South};&lt;br /&gt;Usage:  Direction wall = Direction.North;&lt;br /&gt;It's a nice construct, so perhaps the question is not why   did C# decide to have them, but rather, why did Java choose to   omit them? In Java, you would have to go: &lt;p&gt;Declaration:&lt;/p&gt; public class Direction {&lt;br /&gt; public final static int NORTH = 1;&lt;br /&gt; public final static int EAST = 2;&lt;br /&gt; public final static int WEST = 3;&lt;br /&gt; public final static int SOUTH = 4;&lt;br /&gt;} &lt;p&gt;Usage:&lt;/p&gt; int wall = Direction.NORTH;&lt;br /&gt;Despite the fact the Java version seems to express more, it   doesn't, and is less type-safe, by allowing you to accidentally   assign wall to any int value without the compiler complaining.   To be fair, in my experience of Java programming I haven't   wasted much time on writing a few extra tokens and tracking   down an error because of lack of type-safety here, but   nonetheless, this is nice to have. One benefit of C# is the nice   surprise you get when debugging - if you put a break point on   an enumeration which holds combined enumerations, it will   automatically decode direction to give you a human readable   output, rather than a number you have to decode: &lt;br /&gt;&lt;p&gt;Declaration:&lt;/p&gt; public enum Direction {North=1, East=2, West=4, South=8};&lt;br /&gt;Usage:&lt;br /&gt;Direction direction = Direction.North  Direction.West;&lt;br /&gt;if ((direction &amp; Direction.North) != 0)&lt;br /&gt;    ....&lt;br /&gt; &lt;p&gt;If you put a breakpoint on the if statement, you'll get the human readable version for direction rather than the number 5.&lt;/p&gt;&lt;div class="comment"&gt;&lt;p&gt;The mostly likely reason why enums are absent in Java is that you can get by using classes instead. As I mentioned in previous sections, with classes alone we are not able to express a feature in the world as well as we could with another construct. What are the benefits of the Java philosophy of "if it can be done by a class, then don't introduce a new construct"? It would seem simplicity would be the biggest benefit - a shorter learning curve and the prevention of programmers having to think of multiple ways of doing things. Indeed the Java language has improved on C++ in many ways by aiming for simplicity, such as the elimination of pointers, the elimination of header files, and a single-rooted object hierarchy. However, a common aspect of all these simplifications is they actually make coding - uh - simpler. Leaving out constructs, we've looked at enums, properties and events so far, makes your coding more complicated.&lt;br /&gt;&lt;br /&gt;7. Collections and the Foreach Statement&lt;/p&gt;&lt;/div&gt;&lt;p&gt;C# provides a shorthand for for-loops, which also encourages increased consistency for collections classes:&lt;/p&gt;&lt;p&gt;In Java or C++:&lt;/p&gt; 1. while (! collection.isEmpty()) {&lt;br /&gt;        Object o = collection.get();&lt;br /&gt;        collection.next();&lt;br /&gt; ...&lt;br /&gt;2. for (int i = 0; i &lt;&gt;&lt;p&gt;In C#:&lt;/p&gt; 1. foreach (object o in collection)...&lt;br /&gt;2. foreach (int i in array)... &lt;p&gt;The C# for-loop will work on collection objects (arrays implement a collection). Collection objects have a GetEnumerator() method which returns an Enumerator object. An Enumerator object has a MoveNext method and a Current property.&lt;/p&gt;&lt;br /&gt;&lt;p class="heading2"&gt;&lt;a name="8"&gt;&lt;/a&gt;8. Structs&lt;/p&gt;&lt;p&gt;It is helpful to view C# structs as a construct which makes the C# type system work elegantly, rather than just "a way to write really efficient code if you need to".&lt;/p&gt;&lt;p&gt;In C++, both structs and classes (objects) can be allocated on the stack/in-line or on the heap. In C#, structs are always created on the stack/in-line, and classes (objects) are always created on the heap. Structs indeed allow more efficient code to be created:&lt;/p&gt; public struct Vector {&lt;br /&gt;    public float direction;&lt;br /&gt;    public int magnitude;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;Vector[] vectors = new Vector [1000]; &lt;p&gt;This will allocate the space for all 1000 vectors in one lump, which is much more efficient that had we declared Vector as a class and used a for-loop to instantiate 1000 individual vectors. What we've effectively done is declared the array like we would declare an int array in C# or Java:&lt;/p&gt; int[] ints = new ints [1000]; &lt;p&gt;C# simply allows you to extend the primitive set of types built in to the language. In fact, C# implements all the primitive types as structs. The int type merely aliases System.Int32 struct, the long type aliases System.Int64 struct etc. These primitive types are of course able to be treated specially by the compiler, but the language itself does not make such a distinction. The next section shows how C# takes advantage of this.&lt;/p&gt;&lt;p class="heading2"&gt;&lt;a name="9"&gt;&lt;/a&gt;9. Type Unification&lt;/p&gt;&lt;p&gt;Most languages have primitive types (int, long, etc), and higher level types which are ultimately composed of primitive types. It is often useful to be able to treat primitive types and higher level types in the same way. For instance, it is useful to have collections which can take both ints as well as strings. Smalltalk achieves this by sacrificing some efficiency and treating ints and longs as types like String or Form. Java tries to avoid sacrificing this efficiency, and treats primitive types like in C or C++, but provides corresponding wrapper classes for each primitive - int is wrapped by Integer, double is wrapped by Double. C++'s templates allow code to be written which takes any type, so long as the operations done on that type are provided by that type.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;C# provides a different solution to this problem. In the previous section, I introduced C# structs, explaining how primitive types like int were merely aliases for structs. This allows code like this to be written, since structs have all the methods that the object class does:&lt;/p&gt; &lt;br /&gt;int i = 5;&lt;br /&gt;System.Console.WriteLine (i.ToString());&lt;br /&gt; &lt;br /&gt;&lt;br /&gt;&lt;p&gt;If we want to use a struct as an object, C# will box the struct in an object for you, and unbox the struct when you need it again:&lt;/p&gt; &lt;br /&gt;Stack stack = new Stack ();&lt;br /&gt;stack.Push (i); // box the int&lt;br /&gt;int j = (int) stack.Pop(); // unbox the int&lt;br /&gt; &lt;br /&gt;&lt;br /&gt;&lt;p&gt;Apart from a type-cast required when unboxing structs, this is a seamless way to handle the relationship between structs and &lt;/p&gt;&lt;p&gt;classes. You should bare in mind that boxing does entail the creation of a wrapper object, though the CLR may provide additional optimization for boxed objects.&lt;/p&gt;&lt;div class="comment"&gt;&lt;br /&gt;&lt;p&gt;The designers of C# must have considered templates during their design process. I suspect there were two main reasons for not using templates. The first is messiness - templates can be difficult to mesh with object oriented features, they open up too many (confusing) design possibilities for programmers, and they are difficult to work with reflection. The second is that templates wouldn't be very useful unless the .NET libraries like the collection classes used them. However, if the .NET classes used them, then the 20+ languages which use the .NET classes would have to work with templates too, which may be technically very difficult to achieve.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;It is interesting to note that templates (generics) are being considered for inclusion in the Java language by the Java Community Process. It may be that each company starts singing each other's tunes when Sun says that ".NET suffers from lowest common denominator syndrome", and Microsoft says "Java doesn't have cross-language support".&lt;/p&gt;&lt;p&gt;(Amended 10 August) From reading an interview with Anders Hejlsberg, it appears templates are on the horizon, but not for the first release, for the difficulties which were suggested above. It was very interesting to see that the IL specification was written so that the IL code could represent templates (in a non-destructive way so that reflection works well), while byte-code was not. I've also included a link to the Java Community Process for considering generics in java:&lt;/p&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://windows.oreilly.com/news/hejlsberg_0800.html"&gt;Interview With Anders Hejlsberg and Tony Goodhew&lt;/a&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://java.sun.com/aboutJava/communityprocess/jsr/jsr_014_gener.html"&gt;Java Community Process for adding Generics to Java&lt;/a&gt;&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;&lt;p class="heading2"&gt;&lt;a name="10"&gt;&lt;/a&gt;10. Operator Overloading&lt;/p&gt;&lt;p&gt;Operator overloading allows programmers to build types which feel as natural to use as simple types (int, long, etc.). C# implements a stricter version of operator overloading in C++, but it allows classes such as the quintessential example of operator-overloading, the complex number class, to work well.&lt;/p&gt;&lt;p&gt;In C#, the == operator is a non-virtual (operators can't be virtual) method of the object class which compares by reference. When you build a class, you may define your own == operator. If you are using your class with collections, then you should implement the IComparable interface. This interface has one method to implement, called the CompareTo (object) method, which should return positive, negative, or 0 if "this" is greater, less than, or the same value as the object. You may choose to define &lt;, &lt;=, &gt;=, &gt; methods if you want users of your class to have a nicer syntax. The numeric types (int, long, etc) implement the IComparable interface.&lt;/p&gt;&lt;p&gt;Here's a simple example of how to deal with equality and comparisons:&lt;/p&gt; &lt;br /&gt;public class Score : IComparable&lt;br /&gt;{&lt;br /&gt;    int value;&lt;br /&gt;&lt;br /&gt;    public Score (int score) {&lt;br /&gt;        value = score;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    public static bool operator == (Score x, Score y) {&lt;br /&gt;        return x.value == y.value;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    public static bool operator != (Score x, Score y) {&lt;br /&gt;        return x.value != y.value;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    public int CompareTo (object o) {&lt;br /&gt;        return value - ((Score)o).value;&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;Score a = new Score (5);&lt;br /&gt;Score b = new Score (5);&lt;br /&gt;Object c = a;&lt;br /&gt;Object d = b;&lt;br /&gt; &lt;br /&gt;&lt;br /&gt;&lt;p&gt;To compare a and b by reference:&lt;/p&gt;&lt;br /&gt; System.Console.WriteLine ((object)a == (object)b; // false  &lt;br /&gt;&lt;br /&gt;&lt;p&gt;To compare a and b by value:&lt;/p&gt;&lt;br /&gt; System.Console.WriteLine (a == b); // true &lt;br /&gt;&lt;br /&gt;&lt;p&gt;To compare c and d by reference:&lt;/p&gt;&lt;br /&gt; System.Console.WriteLine (c == d); // false &lt;br /&gt;&lt;br /&gt;&lt;p&gt;To compare c and d by value:&lt;/p&gt;&lt;br /&gt; System.Console.WriteLine (((IComparable)c).CompareTo (d) == 0); // true &lt;br /&gt;&lt;br /&gt;&lt;p&gt;You could also add the &lt;, &lt;=, &gt;=, &gt; operators to the score class. C# ensures at compile time that operators which are logically paired (!= and ==, &gt; and &lt;, &gt;= and &lt;=), must both be defined.&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p class="heading2"&gt;&lt;a name="11"&gt;&lt;/a&gt;11. Polymorphism&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;Virtual methods allow object oriented languages to express polymorphism. This means a derived class can write a method with the same signature as a method in its base class, and the base class will call the derived class's method. By default in Java, all methods are virtual. In C#, like C++, the virtual keyword must be used so that the method will be called by the base class.&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;In C#, it is also required that the override keyword is needed to specify that a method should override a method (or implement an abstract method) of its base class.&lt;/p&gt;&lt;br /&gt;&lt;br /&gt; &lt;br /&gt;Class B {&lt;br /&gt;    public virtual void foo () {}&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;Class D : B {&lt;br /&gt;    public override void foo () {}&lt;br /&gt;}&lt;br /&gt; &lt;br /&gt;&lt;br /&gt;&lt;p&gt;Attempting to override a non-virtual method will result in a compile-time error unless the "new" keyword is added to the declaration, indicating the method is intentionally hiding the base class's method.&lt;/p&gt;&lt;br /&gt;&lt;br /&gt; &lt;br /&gt;Class N : D {&lt;br /&gt;    public new void foo () {}&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;N n = new N ();&lt;br /&gt;n.foo(); // calls N's foo&lt;br /&gt;((D)n).foo(); // calls D's foo&lt;br /&gt;((B)n).foo(); // calls D's foo&lt;br /&gt; &lt;br /&gt;&lt;br /&gt;&lt;p&gt;In contrast to both C++ and Java, requiring the override keyword makes it more clear what methods are overridden when looking at source code. However, requiring the use of the virtual method has its pros and cons. The first pro is that is the slightly increased execution speed from avoiding virtual methods. The second pro is to make clear what methods are intended to be overridden. However, this pro can also be a con. Compare the default option of leaving out a final modifier in Java vs leaving out a virtual modifier in C++. The default option in Java may make your program slightly less efficient, but in C++ it may prevent extendibility, albeit unforeseen, by the implementer of the base class.&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p class="heading2"&gt;&lt;a name="12"&gt;&lt;/a&gt;12. Interfaces&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;&lt;br /&gt;Interfaces in C# are similar to Java interfaces, but can be used with greater flexibility. A class may optionally "explicitly" implement an interface:&lt;/p&gt;&lt;br /&gt;&lt;br /&gt; &lt;br /&gt;public interface ITeller&lt;br /&gt;{&lt;br /&gt;    void Next ();&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;public interface IIterator&lt;br /&gt;{&lt;br /&gt;    void Next ();&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;public class Clark : ITeller, IIterator&lt;br /&gt;{&lt;br /&gt;    void ITeller.Next () {&lt;br /&gt;    }&lt;br /&gt;    void IIterator.Next () {&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt; &lt;br /&gt;&lt;br /&gt;&lt;p&gt;This gives a class two benefits. First, a class can implement several interfaces without having to worry about naming conflicts. Second, it allows a class to "hide" a method if it is not useful for general users of the class. Explicitly implemented methods are invoked by type-casting a class to the interface required:&lt;br /&gt;&lt;br /&gt; &lt;br /&gt;Clark clark = new Clark ();&lt;br /&gt;((ITeller)clark).Next();&lt;br /&gt; &lt;br /&gt;&lt;p&gt;&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p class="heading2"&gt;&lt;a name="13"&gt;&lt;/a&gt;13. Versioning&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;Solving versioning issues has been a major consideration in the .NET framework. Most of these considerations apply to &lt;a href="#20"&gt;assemblies&lt;/a&gt;. There are some quite impressive capabilities such as running multiple versions of the same assembly in the same process.&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;The C# language prevents software failures when new versions of code (most notably the .NET libraries) are made. The C# Language Reference explains this in detail, but I've summarized the problem with a highly condensed example:&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;In Java, supposing we deploy a class called D which derives a class distributed with the VM, called B. Class D has a method called foo which B does not have at the time of distribution. Later, an update is made to class B, which now includes a foo method, and the new VM is installed on the computer running software which uses class D. The software using class D may malfunction because the new implementation of class B will make a virtual call to class D, performing an action with an implementation totally unintended by class B. In C#, class D's foo would have been declared without the override modifier (which expresses the programmer's intention), so the runtime knows to make Class D's foo hide Class B's foo, rather than override it.&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;An interesting quote from the C# reference manual was: "C# addresses this versioning problem by requiring developers to clearly state their intent". Although the use of the word override is one way to state intention, it could also be automatically generated by the compiler by checking to see if a method performs (rather than declares) an override at the time of compilation. This means you can still have Java-like languages (which don't use virtual and override keywords) and still cope with versioning correctly.&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;&lt;br /&gt;Also see &lt;a href="#18"&gt;Field Modifiers&lt;/a&gt;&lt;br /&gt;&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;p class="heading2"&gt;&lt;a name="14"&gt;&lt;/a&gt;14. Parameter Modifiers&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p class="heading3"&gt;"ref" parameter modifier&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;C# (as opposed to Java) lets you pass parameters by reference. The most obvious example to illustrate the point of this is the general purpose swap method. Unlike in C++, you must specify when calling as well as when declaring a method which takes ref parameters:&lt;/p&gt;&lt;br /&gt;&lt;br /&gt; &lt;br /&gt;public class Test&lt;br /&gt;{&lt;br /&gt;    public static void Main ()&lt;br /&gt;    {&lt;br /&gt;        int a = 1;&lt;br /&gt;        int b = 2;&lt;br /&gt;        swap (ref a, ref b);&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    public static void swap (ref int a, ref int b) {&lt;br /&gt;       int temp = a;&lt;br /&gt;       a = b;&lt;br /&gt;       b = temp;&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt; &lt;br /&gt;&lt;br /&gt;&lt;p class="heading3"&gt;"out" parameter modifier&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;There is also an "out" keyword, which is a natural complement to the ref parameter modifier. While the ref modifier requires that a value is definitely assigned before passed into a method, the out modifier requires that the method's implementation definitely assigns the parameter a value before returning.&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p class="heading3"&gt;"params" parameter modifier&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;The params modifier may be added to the last parameter of a method so that the method accepts any number of parameters of a particular type. For example:&lt;/p&gt;&lt;br /&gt;&lt;br /&gt; &lt;br /&gt;public class Test&lt;br /&gt;{&lt;br /&gt;    public static void Main () {&lt;br /&gt;        Console.WriteLine (add (1, 2, 3, 4).ToString());&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    public static int add (params int[] array) {&lt;br /&gt;       int sum = 0;&lt;br /&gt;       foreach (int i in array)&lt;br /&gt;           sum += i;&lt;br /&gt;       return sum;&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt; &lt;br /&gt;&lt;br /&gt;&lt;div class="comment"&gt;&lt;br /&gt;&lt;p&gt;One of the most surprising things when you're learning Java is not being able to pass by reference. It turns out though that after a little while you seldom miss this functionality, and write code which doesn't use it it. When I went over the C# specification for the first time, I often thought "Why have they got this or that functionality, I can code without it". With a little introspection, I realized this wasn't really an argument to show some functionality wasn't useful, but was more an argument to show that you get conditioned into getting by without it.&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;Java did a good thing when it simplified how parameters could be passed when you consider what C++ does. In C++, parameters of a method and a method call pass in values or references, which in addition to having pointers, can lead to unnecessarily complicated code. C# makes passing by reference explicit for both the method and the method call, which greatly alleviates any confusion, thus achieving the same goal as Java, but with greater expressiveness. It is clearly a theme of C# to not hedge programmers into situations where they require a round-about way of achieving something. Remember those Java tutorials that suggest that to overcome the pass-by-reference problem, you should pass a 1-element array to holding your value, or make another class to hold that value?&lt;/p&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;p class="heading2"&gt;&lt;a name="15"&gt;&lt;/a&gt;15. Attributes&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;Both C# and Java contain information such as the access level of a field in the compiled code. C# generalizes this ability, so you can compile custom information about just about any element of code such as a class, method, field and even individual parameters. This information can be retrieved at run-time. Here is a very simple example of a class which makes use of attributes:&lt;/p&gt;&lt;br /&gt;&lt;br /&gt; &lt;br /&gt;[AuthorAttribute ("Ben Albahari")]&lt;br /&gt;class A&lt;br /&gt;{&lt;br /&gt;    [Localizable(true)]&lt;br /&gt;    public String Text {&lt;br /&gt;        get {return text;&lt;br /&gt;        }&lt;br /&gt;        ...&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt; &lt;br /&gt;&lt;br /&gt;&lt;p&gt;Java uses a combination of /** */ and @tag comments to include additional information about classes and methods, but this information (apart from the @deprecated) is not built into the byte code. C# uses the pre-defined attributes ObsoleteAttribute so the compiler can warn you against obsolete code (like @deprecated), and the ConditionalAttribute to enable conditional compilation. Microsoft's new XML libraries utilize attributes to express how fields should be serialized into XML, which means you can easily turn a class into XML and then reconstruct it again. Another apt use for attributes is for the creation of a really powerful class browsing tool. The C# Language Reference explains exactly how to create and use attributes.&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p class="heading2"&gt;&lt;a name="16"&gt;&lt;/a&gt;16. Selection Statements&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;C# lets you govern a switch statement with an integral type, char, enum or (unlike C++ or Java) a string. In Java and C++ if you leave out a break after each case statement you risk having another case statement being executed. I have no idea why this rarely needed error-prone behavior was made the default behavior in Java and C++, and I'm glad to see C# doesn't do this.&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p class="heading2"&gt;&lt;a name="17"&gt;&lt;/a&gt;17. Predefined Types&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;The C# primitive types are basically the same as the ones in Java except they add unsigned types to. We've got sbyte, byte, short, ushort, int, uint, long, ulong, char, float &amp; double. The only surprise here is the 12-byte "decimal" floating point number which can take advantage of the latest processors.&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p class="heading2"&gt;&lt;a name="18"&gt;&lt;/a&gt;18. Field Modifiers&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;Again, the field modifiers are basically the same as the ones in Java. To express fields which can't be modified, C# uses the const and readonly modifiers. A const field modifier is like the Java final field modifier, and compiles so that the actually value is part of the IL code. A readonly modifier compiles so that at run-time the value is evaluated. This allows an upgrade, say to one one of the standard C# libraries, without breaking your deployed code.&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p class="heading2"&gt;&lt;a name="19"&gt;&lt;/a&gt;19. Jump Statements&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;Not many surprises here, apart from perhaps the infamous goto. However, it's really a distant relative of the evil goto statement we remember from basic 20 years ago. A goto statement must point to a label or one of the options in a switch statement. The first usage of pointing to a label is similar to the usage of a continue : label statement in Java, except with a little more freedom. Such a goto statement may point anywhere within its scope, which restricts it to the same method, or finally block if it is declared within one. It may not jump into a loop statement which it is not within, and it cannot leave a try block before the enclosing finally block(s) are executed. The continue statement in C# is equivalent to the continue statement in Java, except it can't point to a label.&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p class="heading2"&gt;&lt;a name="20"&gt;&lt;/a&gt;20. Assemblies, Namespaces &amp;amp; Access Levels&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;In C#, you can organize the components of your source-code (classes, structs, delegates, enums, etc.) into files, namespaces &amp; assemblies.&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;&lt;br /&gt;Namespaces are nothing but syntactic sugar for long class names. For instance, rather than calling a class Genamics.WinForms.Grid you can declare the class as Grid and enclose the class with:&lt;/p&gt;&lt;br /&gt;&lt;br /&gt; &lt;br /&gt;namespace Genamics.WinForms {&lt;br /&gt;    public class Grid {&lt;br /&gt;        ....&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt; &lt;br /&gt;&lt;br /&gt;&lt;p&gt;For classes which use Grid, you can import it using the "using" keyword instead of referring to its full class name Genamics.WinForms.Grid.&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;Assemblies are .exes or .dlls generated from compiling a project of files. The .NET runtime uses the configurable attributes and versioning rules built into assemblies to greatly simplify deployment - no more hacking the registry - just copy the assembly into a directory and it goes. Assemblies also form a type-boundary to deal with type-name collisions, to the extent that multiple versions of an assembly can co-exist in the same process. Each file can contain multiple classes and multiple namespaces. A namespace may also be spread across several assemblies, so there is high level of freedom with this system.&lt;br /&gt;&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;There are five access levels in C#, private, internal, protected, internal protected, and public. Private and public have the same meanings as in Java, noting that in C# the default access level is private, rather than package. Internal access is scoped to assemblies rather than namespaces (which would be more analogous to Java). Internal protected access is equivalent to Java's protected access, and protected access is equivalent to Java's private protected access made obsolete in Java some time ago.&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p class="heading2"&gt;&lt;a name="21"&gt;&lt;/a&gt;21. Pointer Arithmetic&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;Pointer arithmetic can be performed in C# within methods marked with the unsafe modifier. When pointers point to garbage collected objects, the compiler enforces the use of the fixed word to pin the object. This is because garbage collectors rely on moving objects around to reclaim memory, but if this happens when you're dealing with raw pointers you'll be pointing at garbage. The choice of the word "unsafe" I believe is well chosen since it discourages developers from using pointers unless they really need to.&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p class="heading2"&gt;&lt;a name="22"&gt;&lt;/a&gt;22. Rectangular Arrays&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;C# allows both jagged and rectangular arrays to be created. Jagged arrays are pretty much the same as Java arrays. Rectangular arrays allow a more efficient and accurate representation for certain problems. An example of such an array would be:&lt;/p&gt;&lt;br /&gt;&lt;br /&gt; &lt;br /&gt;int [,,] array = new int [3, 4, 5]; // creates 1 array&lt;br /&gt;int [1,1,1] = 5;&lt;br /&gt; &lt;br /&gt;&lt;br /&gt;&lt;p&gt;Using jagged arrays:&lt;/p&gt;&lt;br /&gt;&lt;br /&gt; &lt;br /&gt;int [][][] array = new int [3][4][5]; // creates 1+3+12=16 arrays&lt;br /&gt;int [1][1][1] = 5;&lt;br /&gt; &lt;br /&gt;&lt;br /&gt;&lt;p&gt;In combination with structs, C# can provide a level of efficiency making it a good choice for areas such as graphics and mathematics.&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p class="heading2"&gt;&lt;a name="23"&gt;&lt;/a&gt;23. Constructors and Destructors&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;You can specify optional constructor parameters:&lt;/p&gt;&lt;br /&gt;&lt;br /&gt; &lt;br /&gt;class Test&lt;br /&gt;{&lt;br /&gt;    public Test () : this (0, null) {}&lt;br /&gt;    public Test (int x, object o) {&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt; &lt;br /&gt;&lt;br /&gt;&lt;p&gt;You can specify static constructors:&lt;/p&gt;&lt;br /&gt;&lt;br /&gt; &lt;br /&gt;class Test&lt;br /&gt;{&lt;br /&gt;    static int[] ascendingArray = new int [100];&lt;br /&gt;&lt;br /&gt;    static Test () {&lt;br /&gt;        for (int i = 0; i &lt;&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;Destructors are specified with the C++ naming convention using the ~ symbol. Destructors can only be made for references types and not value types, and cannot be overridden. A destructor can not be explicitly called, since it doesn't make much sense to do so when an object's lifetime is managed by the garbage collector. Each destructor in an object's hierarchy (from the most derived to the least derived) is called before the memory for the object is reclaimed.&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;&lt;br /&gt;Despite the naming similarity with C++, destructors in C# are much more like Java finalizers. This is because they are called by the garbage collector rather than explicitly called by the programmer. Furthermore, like Java finalizers, they cannot be guaranteed to be called in all circumstances (this always shocks everyone when they first discover this). If you are used to programming with deterministic finalization (you know when an object's destructor is called), then you have to adapt to a different model when moving to Java or C#. The model Microsoft recommends and implements throughout the .NET framework is the dispose pattern, whereby you define a dispose() method to for classes which manage foreign resources such as graphics handles or database connections. For distributed programming, the .NET framework provides a leased based model to improve upon DCOM reference counting.&lt;br /&gt;&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p class="heading2"&gt;&lt;a name="24"&gt;&lt;/a&gt;24. Managed Execution Environments&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;The comparison between [C#/IL Code/CLR] and [Java/Byte-Code/JVM] is an inevitable and valid comparison to make. I thought the best way to make sense of these comparisons was to explain why these technologies were made in the first place.&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;With C and C++ programs, you generally compile the source code to assembly language code which will only run on a particular processor and a particular OS. The compiler needs to know which processor it is targeting, because processors vary in their instruction sets. The compiler also needs to know what OS it is targeting, because OSs vary in ways such as how executables work and how they implement some basic C/C++ constructs such as allocating memory. This C/C++ model has been very successful (most software you're using probably has been compiled like this), but has its limitations:&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;Does not provide a program with a very rich interface to interact with other programs (Microsoft's COM was built to address this limitation)&lt;br /&gt;&lt;li&gt;Does not allow a program to be distributed in a form which can be used as is on different platforms&lt;br /&gt;&lt;li&gt;Does not allow a program's execution to be limited to a sand box of safe operations&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;Java addressed these problems in the same way Smalltalk had done before it by having Java compile to byte-code which then runs on a virtual machine. Byte-code maintains the basic structure of a program before it is compiled, thus making it possible for a Java program to richly interact with another program. Byte-code is also machine-independent, which means the same class file can be used on a number of platforms. Finally, the fact that the Java language did not have explicit memory manipulation (via pointers) made it well suited to writing sand-boxed programs.&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;Originally virtual machines had an interpreter which converted a stream of byte-code instructions to machine code on the fly, but this dreadfully slow process was never appealing to the performance conscious programmer. Today most Java Virtual Machines use a Just-In-Time compiler which basically compiles to machine-code class skeletons just before they enter scope and method bodies just before they are executed. It is also possible to convert a Java program to assembly language before it runs to eliminate the overhead in start-up time and memory of a Just-In-Time compiler. As with compiling a Visual C++ program, this process does not necessarily remove the program's dependence on a runtime. The Java runtime (also covered by the term "Java Virtual Machine") will handle many vital parts of the programs execution such as garbage collection and security. This runtime is referred to as a managed execution environment.&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;Though somewhat obscured by terminology, the basic model .NET uses is the same as described above, though it was built to never use intepreting. Important improvements .NET will offer will come from the IL design itself, since the only way Java can match such improvements is by changing the byte-code specification which would generate serious compatibility issues. I don't want to discuss in detail these improvements - it should be left to those rare developers who understand both byte-code and IL-code. For the 99% of developers like myself who realistically aren't going to be studying the IL-Code specification, here are some of the design decisions for IL which are intended to improve upon byte-code:&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;To provide greater type neutrality (helps implementing templates)&lt;br /&gt;&lt;li&gt;To provide greater language neutrality&lt;br /&gt;&lt;li&gt;To always be compiled to assembly language before executing, and never interpreted&lt;br /&gt;&lt;li&gt;To allow additional declarative information to be added to classes, methods, etc., see &lt;a href="#15"&gt;15. Attributes&lt;/a&gt;&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;Currently the CLR has yet to provide multi-OS support, but provides greater interoperability to JVMs in other areas (See &lt;a href="#26"&gt;26. Interoperability&lt;/a&gt;)&lt;br /&gt;&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p class="heading2"&gt;&lt;a name="25"&gt;&lt;/a&gt;25. Libraries&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;A language is pretty much useless without libraries. C# has remarkably few core libraries, but utilizes the libraries of the .NET framework (some of which were built with C#). This article is mainly concerned with addressing the C# language in particular, rather than on .NET, which is best dealt with in a separate article. Briefly, the .NET libraries come with a rich set of libraries including Threading, Collection, XML, ADO+, ASP+, GDI+ &amp;amp; WinForms libraries. Some of these libraries are cross-platform, while others are Windows dependent, but see the next section for a discussion on platform support.&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p class="heading2"&gt;&lt;a name="26"&gt;&lt;/a&gt;26. Interoperability&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;I thought it would be useful to group interoperability into three divisions: Language interoperability, Platform interoperability, and Standards interoperability. While Java has its defining strength in platform interoperability, C# has it's strength in language interoperability. Both have strengths and weaknesses in standards interoperability.&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p class="heading3"&gt;Language Interoperability:&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;This is the level and ease of integration with other languages. Both the Java Virtual Machine and the Common Language Runtime allow you to write code in many different languages, so long as they compile to byte code or IL code respectively. However, the .NET platform has done much more than just allow other languages to be compiled to IL code. NET allows multiple languages to freely share and extend each others libraries to a great extent. For instance, an Eiffel or Visual Basic programmer could import a C# class, override a virtual method of that class, and the C# object would now use the Visual Basic method (polymorphism). In case you were wondering, VB.NET has been massively upgraded (at the expense of compatibility with VB6) to have modern object oriented features.&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;Languages written for .NET will generally plug into the Visual Studio.NET environment and use the same RAD frameworks if needed, thus overcoming the "second rate citizen" effect of using another language.&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;C# provides P/Invoke, which is a much simpler (no-dlls) way to interact with C code than Java's JNI. This feature is very similar to J/Direct, which is a feature of Microsoft Visual J++.&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p class="heading3"&gt;Platform Interoperability:&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;Generally this means OS interoperability, but over the last few years the internet browser has emerged as a platform in itself.&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;C# code runs in a managed execution environment, which is the most important technological step to making C# run on different operating systems. However, some of the .NET libraries are based on Windows, particularly the WinForms library which depends on the nitty gritty details of the Windows API. There is a project to port the Windows API to Unix systems, but this isn't here now and Microsoft have not given any firm indication of their intentions in this area.&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;However, Microsoft hasn't ignored platform interoperability. The .NET libraries provide extensive capabilities to write HTML/DHTML solutions. For solutions which can be implemented with a HTML/DHTML client, C#/.NET is a good choice. For cross-platform projects which require a more complex client interface, Java is a good choice. Kylix, a version of Delphi which allows the same code to compile to both Windows and Linux may also be a good choice for rich cross-platform solutions in the future.&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;Microsoft has submitted the C# specification as well as parts of the .NET specification to the ECMA standards body.&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p class="heading3"&gt;Standards Interoperability:&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;These are all the standards like databases systems, graphics libraries, internet protocols, and object communication standards like COM and CORBA, that the language can access. Since Microsoft owns or plays a big role in defining many of these standards, they are in a very good position to support them. They of course have business motivations (I'm not saying they are or are not justified) to provide less support for standards which compete with their own - for instance - CORBA competes with COM and OpenGL competes with DirectX. Similarly, Sun's business motivations (again I'm not saying they are or are not justified) means Java doesn't provide as good support for Microsoft standards as it could.&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;C# objects, since they are implemented as .NET objects, are automatically exposed as COM objects. C# thus has the ability to expose COM objects as well as to use COM objects. This will allow the huge base of COM code to be integrate with C# projects. .NET is a framework which can eventually replace COM - but there is so much deployed COM code that by the time this happens I'm sure .NET will be replaced by the next wave of technology. Anyway, expect .NET to have a long and interesting history!&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p class="heading2"&gt;&lt;a name="27"&gt;&lt;/a&gt;27. Conclusion&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;I hope this has given you a feel for where C# stands in relation to Java and C++. Overall, I believe C# provides greater expressiveness and is more suited to writing performance-critical code than Java, while sharing Java's elegance and simplicity, which makes both much more appealing than C++.&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;Author: Ben Albahari&lt;br /&gt;Company: Genamics&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/15836190-113036358537016459?l=forthosewhomatters.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://forthosewhomatters.blogspot.com/feeds/113036358537016459/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=15836190&amp;postID=113036358537016459' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/15836190/posts/default/113036358537016459'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/15836190/posts/default/113036358537016459'/><link rel='alternate' type='text/html' href='http://forthosewhomatters.blogspot.com/2005/10/comparative-overview-of-c.html' title='A Comparative Overview of C#'/><author><name>For Those Who Matter</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-15836190.post-113034435774577434</id><published>2005-10-26T09:24:00.000-07:00</published><updated>2005-10-26T09:32:37.760-07:00</updated><title type='text'>ASP.NET projects in Visual Studio .NET 2005</title><content type='html'>In Visual Studio .Net 2003 and its below, an ASP .Net project is tied to IIS server. This creates lots of problems.&lt;br /&gt;&lt;br /&gt;In Visual Studio .Net 2005, there is not a dependency on IIS. Developers will be able to create Web applications on their hard disk. When the developers browse or debug the applications from the IDE, a small Web server is started on a unique port to serve the requests.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/15836190-113034435774577434?l=forthosewhomatters.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://forthosewhomatters.blogspot.com/feeds/113034435774577434/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=15836190&amp;postID=113034435774577434' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/15836190/posts/default/113034435774577434'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/15836190/posts/default/113034435774577434'/><link rel='alternate' type='text/html' href='http://forthosewhomatters.blogspot.com/2005/10/aspnet-projects-in-visual-studio-net.html' title='ASP.NET projects in Visual Studio .NET 2005'/><author><name>For Those Who Matter</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-15836190.post-113027925859823957</id><published>2005-10-25T15:07:00.000-07:00</published><updated>2005-10-25T15:27:38.610-07:00</updated><title type='text'>How composite web controls keep the state of children controls</title><content type='html'>Composite controls contain a set of children controls.  How do these children controls's state get updated in a postback event?&lt;br /&gt;&lt;br /&gt;All the children 's state is saved in viewstate according to the index that the child control in the child control tree. When recreating the page, all children controls are recreated by calling CreateChildrenControl(); After the children control are created, the values in viewstate will be restored. Any child control that is addes to the control, its state will be updated according the value in viewstate.&lt;br /&gt;&lt;br /&gt;One thing is very important is that in viewstart child control is referenced by its index when it is added to the control tree. Later it is restored according to the index in the control tree also. So if for some reason the indexes are different between not postback and postback, there will be a problem. (For example, render is not called in a postback senario but is called in a not postback senario. If the indexes are changed inside render function, there will be a problem.) To prevent this from happening,  you need override the property "Controls" in the control like the following:&lt;br /&gt;&lt;br /&gt;public override ControlCollection Controls&lt;br /&gt;{&lt;br /&gt;     Get {&lt;br /&gt;              EnsureChildControls();&lt;br /&gt;              return base.Controls;&lt;br /&gt; }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;This code causes the child controls that you created in CreateChildControls to be added to the control tree before other other controls(if any) are added by user code. The child controls you created in CreateChildControls are thus recreated pm postback in the same order in which they were saved. This allows the page framework to restore their state by using view state.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/15836190-113027925859823957?l=forthosewhomatters.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://forthosewhomatters.blogspot.com/feeds/113027925859823957/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=15836190&amp;postID=113027925859823957' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/15836190/posts/default/113027925859823957'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/15836190/posts/default/113027925859823957'/><link rel='alternate' type='text/html' href='http://forthosewhomatters.blogspot.com/2005/10/how-composite-web-controls-keep-state.html' title='How composite web controls keep the state of children controls'/><author><name>For Those Who Matter</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-15836190.post-113008248192648585</id><published>2005-10-23T08:10:00.000-07:00</published><updated>2005-10-23T08:48:03.013-07:00</updated><title type='text'>Custom Attributes</title><content type='html'>Custom attribute allows you to define some information that can be applied to any type in the metadata table. Using these information, you can change the way your codes execute.&lt;br /&gt;&lt;br /&gt;To define a custom attribute, you just need to inherit the System.Atribute class and name your class XXXAttribute as a convention. Your attribute will be normally used by calling its constructor. Most time, the state is set by the the parameters passed from the constructor.&lt;br /&gt;&lt;br /&gt;Use attribute is not like using normal types. You basically put it before the type which you want to control later.  For example,&lt;br /&gt;&lt;br /&gt;[XXAttribute("something", "something else")]&lt;br /&gt;Yourclass&lt;br /&gt;{&lt;br /&gt;///&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;Using reflection, you can check the presence of attributes.  Each type has a method called "IsDefined", it can take an attribute type as a parameter, if the attribute type is associated with it, it will return true.&lt;br /&gt;&lt;br /&gt;IsDefined can help you check the presence of an attribute. But if you want to check the state of an attribute, you must construct an instance of an attribute. To do this, you must either call GetCustomAttributes or GetCustomAttribute. Pay attention here, these methods really take time. If you need frequently use value from an attribute, you better think of caching it somewhere.&lt;br /&gt;&lt;br /&gt;There are some frequently used attributes such as serializable. Emitting the full attribute inforation into the metadata would increase the size of the managed module significantly.  When comiling, these attribute are specially emitted in the metadata as bits. We call these attibute as pseudo-custom attribute.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/15836190-113008248192648585?l=forthosewhomatters.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://forthosewhomatters.blogspot.com/feeds/113008248192648585/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=15836190&amp;postID=113008248192648585' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/15836190/posts/default/113008248192648585'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/15836190/posts/default/113008248192648585'/><link rel='alternate' type='text/html' href='http://forthosewhomatters.blogspot.com/2005/10/custom-attributes.html' title='Custom Attributes'/><author><name>For Those Who Matter</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-15836190.post-112994588078157877</id><published>2005-10-21T18:30:00.000-07:00</published><updated>2006-01-09T14:48:24.520-08:00</updated><title type='text'>Strong Name and Assembly</title><content type='html'>A strong name consists of the assembly's identity — its simple text name, version number, and culture information (if provided) — plus a public key and a digital signature.&lt;br /&gt;&lt;br /&gt;To create a strong name, you need a crytographic key pair. A Security Name tool (sn.exe) can be used to generate a key pair. The ke pair can be kept in a file or in your local machine's Crytographic Service Provider. This command&lt;br /&gt;&lt;br /&gt;sn -k Testkey.snk&lt;br /&gt;&lt;br /&gt;will generate a file.&lt;br /&gt;&lt;br /&gt;For keys stored in a file, use System.Reflection.AssemblyKeyFileAttribute. For keys stored in the CSP use System.Reflection.AssemblyKeyNameAttribute.&lt;br /&gt;&lt;br /&gt;If you do not have access to the private key you need to generate the strong name, you can choose to delay sign your assembly.&lt;br /&gt;&lt;br /&gt;Since the assembly in the example does not have a valid signature, the signature validation performed by the common language runtime will fail when you try to install the assembly into the global assembly cache or load it from an application directory. However, the Strong Name tool can be used to disable signature verification of a particular assembly by using the -Vr option: sn -Vr DelaySign.dll&lt;br /&gt;&lt;br /&gt;A valid signature must be generated before the assembly is shipped to customers using sn -R. This is typically done by the company signing entity. You must supply the full key pair to create a valid signature.&lt;br /&gt;&lt;br /&gt;sn -R DelaySign.dll Testkey.snk&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/15836190-112994588078157877?l=forthosewhomatters.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://forthosewhomatters.blogspot.com/feeds/112994588078157877/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=15836190&amp;postID=112994588078157877' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/15836190/posts/default/112994588078157877'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/15836190/posts/default/112994588078157877'/><link rel='alternate' type='text/html' href='http://forthosewhomatters.blogspot.com/2005/10/strong-name-and-assembly.html' title='Strong Name and Assembly'/><author><name>For Those Who Matter</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-15836190.post-112994140026210672</id><published>2005-10-21T15:41:00.000-07:00</published><updated>2005-10-21T17:53:11.026-07:00</updated><title type='text'>Module, Assembly and AppDomain</title><content type='html'>A managed module contains PE header(indicates the type of files:GUI, CUI or DLL; and so on), CLR header(includes CLR version, strong name, and so on), Metadata(includes two main tables: table describing the types and members, table describing the types and members referenced by the source code). By module itselt, CLR can not load it. Module has to be in an assembly to let CLR load it.&lt;br /&gt;&lt;br /&gt;The command "csc /t:module RUT.cs" will tell the compiler to compile RUT.cs into a managed modul - RUT.netmodule.&lt;br /&gt;&lt;br /&gt;An assemby is a logical grouping of one or more managed modules or resource files. It is the smallest unit of reuse, security, and versioning. An assembly must contains a block of data called manifest which contains tables decribing the files that make up the assembly, and so on.&lt;br /&gt;&lt;br /&gt;The command "csc /out:JeffTypes.dll /t:libray /addmodule:RUT.netmodule FUT.cs" will produce an assembly which consists of JeffTypes.dll and the RUT.netmodule.&lt;br /&gt;&lt;br /&gt;An AppDomain is a logical container for a set of assemblies. Code in a managed assembly can tell the CLR to create additional AppDomains. AppDomains are isolated from one another. AppDomains can be unloaded. AppDomains can be individually secured and configured(By using a secure-related feature that determines the maximum rights granted to assemblies running in the AppDomain. SetAppDomainPolicy method can also set a security policy for the domain.)&lt;br /&gt;&lt;br /&gt;The first AppDomain created when the CLR initializes is called the default AppDomain; this AppDomain is destroyed only when the Windows process terminates.&lt;br /&gt;&lt;br /&gt;Strongly named assemblies are loaded in a domain-neutral fashion to conserve operating system resources. The CLR maintains a special loader heap for assemblies that are loaded in a domain-neutral fashion. Assemblies loaded this way can't be unloaded until the process terminates. That's why whenever we update some strongly named assemblies, we have to do an iisreset to have those updates in use.&lt;br /&gt;&lt;br /&gt;Thread's static GetDomain method can obtain a reference to the System.AppDomain object to identify the AppDomain that the thread is currently executing in.&lt;br /&gt;&lt;br /&gt;System.AppDomain's static CurrentDomain can get a reference to an AppDomain object that identifies the AppDomain containing the calling code. The AppDomain object's GetAssembles method returns an array of System.Reflection.Assembly elements. Each assembly has a method GetModules that returns an array of System.Reflection.Module classes. Each module has a method GetTypes that returns an array of System.Reflection.MemberInfo elements which identifies a member(constructor, method, field, property, event, or nested type) of the type.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/15836190-112994140026210672?l=forthosewhomatters.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://forthosewhomatters.blogspot.com/feeds/112994140026210672/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=15836190&amp;postID=112994140026210672' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/15836190/posts/default/112994140026210672'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/15836190/posts/default/112994140026210672'/><link rel='alternate' type='text/html' href='http://forthosewhomatters.blogspot.com/2005/10/module-assembly-and-appdomain.html' title='Module, Assembly and AppDomain'/><author><name>For Those Who Matter</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-15836190.post-112992269304204734</id><published>2005-10-21T11:43:00.000-07:00</published><updated>2006-01-17T13:55:20.213-08:00</updated><title type='text'>Error Handling in C#, Java and C++</title><content type='html'>All these languages has throw, try, catch and finally key words.&lt;br /&gt;&lt;br /&gt;Java has another key word throws which is used when declaring fuctions. If a function is defined with throws certain exception, all the users of the function have either rethrow the exception or catch the exception. But both C++ and C# does not have this function.&lt;br /&gt;&lt;br /&gt;If there any exception happening inside a catch block or finally block, if that block gets executed (in finally case, finally block always gets executed.)  An unhandled exception will throw and the process with exit.&lt;br /&gt;&lt;br /&gt;Unhandled C++ Exceptions&lt;br /&gt;&lt;br /&gt;If a matching handler (or ellipsis catch handler) cannot be found for the current exception, the predefined terminate function is called. (You can also explicitly call terminate in any of your handlers.) The default action of terminate is to call abort. If you want terminate to call some other function in your program before exiting the application, call the set_terminate function with the name of the function to be called as its single argument. You can call set_terminate at any point in your program. The terminate routine always calls the last function given as an argument to set_terminate. For example:&lt;br /&gt;&lt;br /&gt;#include &lt;eh.h&gt;    // For function prototypes&lt;br /&gt;//...&lt;br /&gt;void term_func() { // ... }&lt;br /&gt;int main()&lt;br /&gt;{&lt;br /&gt;    try&lt;br /&gt;    {&lt;br /&gt;        // ...&lt;br /&gt;        set_terminate( term_func );&lt;br /&gt;        // ...&lt;br /&gt;        throw "Out of memory!"; // No catch handler for this exception&lt;br /&gt;    }&lt;br /&gt;    catch( int )&lt;br /&gt;    {&lt;br /&gt;        cout &lt;&lt; "Integer exception raised.";&lt;br /&gt;    }&lt;br /&gt;    return 0;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;The term_func function should terminate the program or current thread, ideally by calling exit. If it doesnt, and instead returns to its caller, abort is called.&lt;br /&gt;&lt;br /&gt;For more information about C++ exception handling, see the C++ Annotated Reference Manual by Margaret Ellis and Bjarne Stroustrup.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;ASP.NET&lt;br /&gt;&lt;br /&gt;The UnhandledExceptionEventHandler Delegate&lt;br /&gt;The UnhandledExceptionEventHandler delegate can be used as a means to handle exceptions that are not handled by your application code. The method you associate with the UnhandledExceptionEventHandler delegate will be executed when an unhandled exception occurs.&lt;br /&gt;&lt;br /&gt;In most ASP.NET Web applications, your application will use Application_Error, instead of the UnhandledExceptionEventHandler, to serve as your application's last chance to handle the exception.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/15836190-112992269304204734?l=forthosewhomatters.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://forthosewhomatters.blogspot.com/feeds/112992269304204734/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=15836190&amp;postID=112992269304204734' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/15836190/posts/default/112992269304204734'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/15836190/posts/default/112992269304204734'/><link rel='alternate' type='text/html' href='http://forthosewhomatters.blogspot.com/2005/10/error-handling-in-c-java-and-c.html' title='Error Handling in C#, Java and C++'/><author><name>For Those Who Matter</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-15836190.post-112981960816038612</id><published>2005-10-20T07:38:00.000-07:00</published><updated>2005-10-20T08:49:04.800-07:00</updated><title type='text'>What is "marshal"?</title><content type='html'>In distributed computing, the word "marshal" is used a lot. What does it really mean by computer scientist?&lt;br /&gt;&lt;br /&gt;This concept is actually related to the "object" concept in OO design. In OO desigh, we use object to as the unit to describle the real world. In computing, an object instance can be accessed by referencing its address in the memory. In distributed computing, sometimes, we want to pass an object instance from one application domain or process to another one. To do this, we can not actually give out the instance address not only because of security concern but also in most case it does not make sense to give the memory address on one machine to another machine. Therefore, the really process is we package all the field values and properties of that intance into a string or an bit array. This process is called serialization. On the receiver side, it will use the information to construct a new instance of that object. This process is called deserialization. The whole process of serialization and deserialization is called "marshaling".&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/15836190-112981960816038612?l=forthosewhomatters.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://forthosewhomatters.blogspot.com/feeds/112981960816038612/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=15836190&amp;postID=112981960816038612' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/15836190/posts/default/112981960816038612'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/15836190/posts/default/112981960816038612'/><link rel='alternate' type='text/html' href='http://forthosewhomatters.blogspot.com/2005/10/what-is-marshal.html' title='What is &quot;marshal&quot;?'/><author><name>For Those Who Matter</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-15836190.post-112965285852967693</id><published>2005-10-18T08:57:00.000-07:00</published><updated>2005-12-12T16:00:37.683-08:00</updated><title type='text'>.Net Delegate, Event and Function Pointer</title><content type='html'>.Net introduce a new concept of Delegate. It looks just like function pointer in C++/C. But it is not really the same. Both delegate and function pointer can be used to reference some function address. Thus, given the right parameters, delegate and function pointer can both be used to invoke targeted function get executed. This feature has been used a lot in callback function seneriao which applies to both cases. However, delegate has been given more features than function pointers. The notest one is multcast delegate. User can chain multiple function reference together and when the delegate is invoked, all the chained function will be called and executed. User can also remove function reference from the list.&lt;br /&gt;In software engineering, event is usually used for implementing observer pattern. There are publisher and subscriber. Publisher has knowledge about certain events and exposes events. Subscribers are interested in knowing whether certain event has happened and if yes, it might do something. In .Net, event is defined based on delegate. The publisher exposes an event and subcribers can subscribe the event by registering its own delegate instance (which references to a function it knows) to the event. Subscribers can also unregister its interest. When certain event happens, the publisher will call all the functions which the subscribers supply.&lt;br /&gt;Event basically packets some features of delegates related to publisher and subscriber. Only publisher has fully control to the list of event handlers. Subscriber can only register or unregister its own event handler.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/15836190-112965285852967693?l=forthosewhomatters.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://forthosewhomatters.blogspot.com/feeds/112965285852967693/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=15836190&amp;postID=112965285852967693' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/15836190/posts/default/112965285852967693'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/15836190/posts/default/112965285852967693'/><link rel='alternate' type='text/html' href='http://forthosewhomatters.blogspot.com/2005/10/net-delegate-event-and-function.html' title='.Net Delegate, Event and Function Pointer'/><author><name>For Those Who Matter</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-15836190.post-112958130105199226</id><published>2005-10-17T13:27:00.000-07:00</published><updated>2005-10-17T13:35:01.056-07:00</updated><title type='text'>bottom line text cut off by crystal report</title><content type='html'>Crystal keeps messing up with text blocks when exporting ot word format.  I have a text block which is encoded with HTML. The block contains bold and plain text. And I set the font size to 8.5(Thanks to Crystal for this messing up also. It cuts the font size 0.5 pt off when exporting to MS Word). Crystal keeps cutting the bottom line text off. It looks like it calculates the size of the box wrong. If I give the font size an integer, the problem disappears. But it sticking there if I set the font size to 8.5 or something alike. I tried lots of ways to get rid of this problem, but did not work. Finally, I had to add a border around the block and make the border color invisible. This does helps. Just hope it works in all cases!!!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/15836190-112958130105199226?l=forthosewhomatters.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://forthosewhomatters.blogspot.com/feeds/112958130105199226/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=15836190&amp;postID=112958130105199226' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/15836190/posts/default/112958130105199226'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/15836190/posts/default/112958130105199226'/><link rel='alternate' type='text/html' href='http://forthosewhomatters.blogspot.com/2005/10/bottom-line-text-cut-off-by-crystal.html' title='bottom line text cut off by crystal report'/><author><name>For Those Who Matter</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-15836190.post-112931999098163080</id><published>2005-10-14T12:27:00.000-07:00</published><updated>2005-10-14T12:59:50.990-07:00</updated><title type='text'>Building a complete COM+ Server component using C# and .NET</title><content type='html'>Each .NET class that's supposed to run under COM+ needs to derive from the System.ServicedComponent class. This base class provides default implementations of the classic MTS/COM+ interface IObjectControl - Activate(), Deactivate(), and CanBePooled(). You can override the default implementations if you wish to do so.&lt;br /&gt;&lt;br /&gt;.Net uses attributes to define many COM+ fetures.  The Belowing is a snippet written with C#.&lt;br /&gt;&lt;br /&gt;////////////////////////////////////////////////////////////////////////////////////&lt;br /&gt;using System;&lt;br /&gt;using System.Runtime.InteropServices;&lt;br /&gt;using System.EnterpriseServices;&lt;br /&gt;// Include the following for the Trace class&lt;br /&gt;using System.Diagnostics;&lt;br /&gt;// Include the following for Windows Message Box&lt;br /&gt;using System.Windows.Forms;&lt;br /&gt;&lt;br /&gt;namespace COMPlus&lt;br /&gt;{&lt;br /&gt;/// Specify a name for your serviced component&lt;br /&gt;[ ProgId( "COM+ Sample" ) ]&lt;br /&gt;/// Add content to hosting COM+ App's description field&lt;br /&gt;[ Description( "COM+ Sample Server With C#" ) ]&lt;br /&gt;/// Configure component's Transaction Option&lt;br /&gt;[ Transaction( TransactionOption.Required ) ]&lt;br /&gt;/// Configure component's object pooling&lt;br /&gt;[ ObjectPooling( MinPoolSize = 5, MaxPoolSize = 10, CreationTimeout = 20 ) ]&lt;br /&gt;/// Specify COM+ Context Attributes&lt;br /&gt;[ MustRunInClientContext( false ) ]&lt;br /&gt;/// Enable event tracking&lt;br /&gt;[ EventTrackingEnabled( true ) ]&lt;br /&gt;/// Enable JITA for the component&lt;br /&gt;[ JustInTimeActivation( true ) ]&lt;br /&gt;/// Enable Construction String Support for the component&lt;br /&gt;[ ConstructionEnabled( Enabled=true, Default="Hong Server" ) ]&lt;br /&gt;/// Configure activity-based Synchronization for the component&lt;br /&gt;[ Synchronization( SynchronizationOption.Required ) ]&lt;br /&gt;/// Indicate the type of class interface that will be generated for this class&lt;br /&gt;[ ClassInterface( ClassInterfaceType.AutoDual ) ]&lt;br /&gt;///&lt;br /&gt;public class AccountManager : ServicedComponent&lt;br /&gt;{&lt;br /&gt;/// &lt;summary&gt;&lt;br /&gt;/// Public No-argument Default Constructor&lt;br /&gt;/// &lt;/summary&gt;&lt;br /&gt;public AccountManager()&lt;br /&gt;{&lt;br /&gt;}&lt;br /&gt;public string Hello()&lt;br /&gt;{&lt;br /&gt;return "Hello";&lt;br /&gt;}&lt;br /&gt;/// &lt;summary&gt;&lt;br /&gt;/// Do context specific initialization in this method&lt;br /&gt;/// &lt;/summary&gt;&lt;br /&gt;override protected void Activate ()&lt;br /&gt;{&lt;br /&gt;MessageBox.Show ("Bank::Activate() invoked...");&lt;br /&gt;}&lt;br /&gt;/// &lt;summary&gt;&lt;br /&gt;/// Do context specific cleanup in this method&lt;br /&gt;/// &lt;/summary&gt;&lt;br /&gt;override protected void Deactivate ()&lt;br /&gt;{&lt;br /&gt;MessageBox.Show ("Bank::Deactivate() invoked...");&lt;br /&gt;}&lt;br /&gt;/// &lt;summary&gt;&lt;br /&gt;/// Object Pooling support method&lt;br /&gt;/// &lt;/summary&gt;&lt;br /&gt;/// &lt;returns&gt;true if pooling is supported, false if not&lt;/returns&gt;&lt;br /&gt;override protected bool CanBePooled ()&lt;br /&gt;{&lt;br /&gt;MessageBox.Show ("Bank::CanBePooled() invoked...");&lt;br /&gt;return true;&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;////////////////////////////////////////////////////////////////////////////////&lt;br /&gt;&lt;br /&gt;A managed COM+ component needs be put into the GAC. So you need give a strong name to your assemply. Use the tool "sn -k keyfile.key" to generated a pair of keys for you and then reference the key files in your assemblyInfo.cs file. In the project properties window, under the "General" tab, there is  a box labelled "Wrap Assemply for Active/COM objects, put the key file full name there also.&lt;br /&gt;&lt;br /&gt;After you get ready of your key pair,  use "gacutil /your.dll" to put your assemply in the GAC so that COM+ service has a shared place to locate your assemply.&lt;br /&gt;&lt;br /&gt;Now we have an assemply in the GAC, we need configuring it in the COM+ Catalog. We need generate a COM Type Library(tlbexp.exe). and register the type in the system registry(regasm.exe).  We also have to make sure that we enter the right information into the COM+ Catalog(RegDB). Forturnately, we dont have to walk those many steps. The .Net SDK provides an additional tool called Register Services uitility(regsvcs.exe). This utility simplifies the process by making sure that all required details are taken care of in a simple step. It performs the following functions:&lt;br /&gt;1) Our Assempley is loaded into memory&lt;br /&gt;2) Our Assempley is registered( just like using regasm.exe)&lt;br /&gt;3) A COM Type Library(.tlb file) is generated and registered( just like using tlbexp.exe)&lt;br /&gt;4) The generated COM Type library is installed in the specified COM+ application.&lt;br /&gt;5) Our Components are configured according to the attributes that we specified in the type definitions.&lt;br /&gt;&lt;br /&gt;We can use "/fc" option to instruct the tool to build a new COM+ application if one does not currently exist.&lt;br /&gt;&lt;br /&gt;After all this, a managed COM+ server is done.&lt;br /&gt;&lt;br /&gt;You can then enjoy the "transaction, pool" fearures that COM+ container supplies.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/15836190-112931999098163080?l=forthosewhomatters.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://forthosewhomatters.blogspot.com/feeds/112931999098163080/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=15836190&amp;postID=112931999098163080' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/15836190/posts/default/112931999098163080'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/15836190/posts/default/112931999098163080'/><link rel='alternate' type='text/html' href='http://forthosewhomatters.blogspot.com/2005/10/building-complete-com-server-component.html' title='Building a complete COM+ Server component using C# and .NET'/><author><name>For Those Who Matter</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-15836190.post-112508638693985616</id><published>2005-08-26T12:49:00.000-07:00</published><updated>2005-08-26T12:59:46.940-07:00</updated><title type='text'>Crystal Report - The bottom Line Text Are Cut Off</title><content type='html'>I have a text box, in which "allow grow" has been set to 0 that means the box can grow to the full length of the text. Unfortunately, the bottom line text are always get cut. If I change the font size to smaller ones, or add a border around, it looks fine. But this is annoying and at most time it is not acceptable. I almost told the production that I was going to gave up, though this would disappoint them another time. But, suddenly, I ran to the idea that why I just delete the shitting one and create a new one. Yes, it works!!! Weired crystal again.&lt;br /&gt;&lt;br /&gt;I really should not disappoint my colleagues, neither does my friends. Offerring an endless effort  is alway better than simply giving up.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/15836190-112508638693985616?l=forthosewhomatters.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://forthosewhomatters.blogspot.com/feeds/112508638693985616/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=15836190&amp;postID=112508638693985616' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/15836190/posts/default/112508638693985616'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/15836190/posts/default/112508638693985616'/><link rel='alternate' type='text/html' href='http://forthosewhomatters.blogspot.com/2005/08/crystal-report-bottom-line-text-are.html' title='Crystal Report - The bottom Line Text Are Cut Off'/><author><name>For Those Who Matter</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry></feed>
