суббота, 21 августа 2010 г.

Actionscript 3.0 type casting and type checking



Type casting and type checking have always been central to any computer programming language, especially in Object Oriented languages like Actionscript.
In fact, knowing what type of object you are receiving as a parameter or the ability to "transform" your object into another type so that you can pass it along to method calls and class properties are key to one of the most important concepts of Object Orientation:Polymorphism.
According to this principle, any object that extends from a certain hierarchical line (class inheritance or interface implementation) can be used in substitution of any of its ancestors. This results from the fact that descendants have the exact same external programmable interface as their ancestors (either implicitly by means of class inheritance, or by mandatory interface implementation).
Automatic type casting
Sometimes type casting occurs automatically. For instance if you set a property typed asObject with a DisplayObject (which is an Object's descendant), Flash automatically casts that DisplayObject to Object. In other words, whenever you use a descendant in place of one of its ancestors, it automatically is cast to that ancestor's type.
This doesn't mean, however, that the object ceased to be an instance of the descendant type. Only that, in that particular reference in a class property or method argument, it is known as being of the ancestor type. And it will carry that type whenever it is accessed through that property or argument. In other words, what determines the type of the object you are accessing is not the instance creation type, but the type of the property or parameter you're using to access it.
Explicit type casting
Since the object instance doesn't loose its creation type when being cast to an ancestor type, it may still be used whenever that descendant type is required. This is where it gets interesting: If you are trying to set a property of the descendant type using an instance created with that same type but stored in a variable of one of its ancestor types, Flash will complain about type incompatibility.
In order to be able to do this you'll have to explicitly cast the instance back to the descendant type. It sounds somewhat redundant that you have to cast an object to a type that you know it already is, but if you remember that what determines the type is not the instance but the variable used to access it, it makes perfect sense.
Actionscript provides two different techniques for type casting and one for type checking. For type casting your either use the cast operation or the as operator.
The cast operation
Performing a cast operation is very simple. You just have to surround the variable with parenthesis and prepend it with the class into which it's going to be cast.
var receivingVariable:DisplayObject = DisplayObject(objectReference);


The as operator
Using the as operator is equally simple. Just place it between the variable and the Class name like this:
var receivingVariable:DisplayObject = objectReference as DisplayObject;
If you're casting just to reach a property or method of the object you can still use the asoperator:
(objectReference as DisplayObject).alpha = 0;
Yet in this particular case, I would recommend the cast operation instead. I will explain why in a moment.
When casting objects bear in mind that it can fail due to a number of reasons that are beyond the scope of this post and involve concepts like type conversion and boxing.
Differences between the cast operation and the as operator
Both the cast operation and theas operator, when successful, have the same result. They return a reference to the target instance as being of the cast type.
They only differ in how they deal with failure to cast. The cast operation throws a runtimeTypeError if the cast fails, while the as operator returns a null value.
When should you use one or the other?
If you are absolutely certain that the cast will succeed, or if you are willing to surround each cast with a try catch statement or you don't mind your application throwing runtime errors all over, you can safely use the cast operation.
If, on the other hand, you prefer to be able to deal with cast errors elegantly without having to surround each one with a try catch, you should use the as operator.
I tend to prefer the as operator as it makes the code more readable (the cast operation can be confused with constructor invocation and type conversion operations) and is more in sync with the type checking is operator, which I'll present in a moment.
The only time when I absolutely favor the cast operation is when I'm only doing the cast to access a property or method of the object. The reason why I do this is because invoking a property or a method in a null value (returned by the as operator in case of cast failure) will throw a null reference runtime error instead of a type runtime error and as a best practice it is always best to get your errors right so that you don't end up chasing for them in the wrong places.
Type checking
Type checking can easily be done using the is operator in exactly the same way as the asoperator:
var test:Boolean = objectReference is DisplayObject;
The is operator returns a Boolean value stating whether the object is an instance of that type or interface or any of its ancestors.
It would be interesting to know if there are some impacts performance and memory wise when using any of these techniques and which would be best to get that last performance crunch you need. Maybe in a future post. Stay tuned to InsideRIA for updates

среда, 23 июня 2010 г.

HttpException: Maximum request length exceeded



I have come across this error multiple times at work. This problem occurs because the default value for the maxRequestLength parameter in the section of the Machine.config or Web.Config file is 4096 (4 megabytes). As a result, files that are larger than this value are not uploaded by default.
To resolve this problem, use one of the following methods:


  • In the Machine.config file, change the maxRequestLength attribute of the<httpruntime> configuration section to a larger value. This change affects the whole computer.
  • In the Web.config file, override the value of maxRequestLength for the application. For example, the following entry in Web.config allows files that are less than or equal to 1 GB to be uploaded:
                         <httpruntime maxrequestlength="1048576">
Max value for maxRequestLength attribute is "1048576" (1 GB) for .NET Framework 1.0 or 1.1 and "2097151" (2 GB) for .NET Framework 2.0.
Note: During the upload process of large files, built-in ASP.NET loads the whole file in memory before the user can save the file to the disk. Therefore, the process may recycle because of the memoryLimit attribute of the processModel tag in the Machine.config file. More info you can find in Microsoft KB article:http://support.microsoft.com/default.aspx?scid=kb;EN-US;295626

четверг, 10 июня 2010 г.

C# : Everything about DateTime and TimeSpan



Motivation

Sometimes, while writing programs, we can get into situations when we need to measure execution times of various tasks.
Each programming language provides some mechanism to retrieve the current time from the system. If we read and store the system time at various moments, we can compute time intervals by substracting the values of system time taken at diffent moments.
We will see how to read the system time and how to measure time intervals in C#.

Reading the system time in C#

In C#, the DateTime class is used for storing the value of the system time at a specified moment. A DateTime instance stores both date and time information. The DateTime class can be found in the System namespace.
In order to retrieve the current system time, we can use the static property Now of the DateTime class. For example the following two lines of code


DateTime currentSystemTime = DateTime.Now;
Console.WriteLine(currentSystemTime);

print out something like this:


4/17/2005 4:05:35 PM

We can print the date and time information stored in a DateTime instance in various formats, but we do not focus on them here, since our purpose is only to see how to measure time intervals.

Measuring time intervals in C#

In C#, there exists a dedicated class that stores information about a time interval. The name of the class is TimeSpan and it can be found in the System namespace.
The TimeSpan class is very easy to use. If we have an instance of TimeSpan class, we can assign to it directly a difference of two DateTime instance. See the code below to see how to do this.



/* Read the initial time. */
DateTime startTime = DateTime.Now;
Console.WriteLine(startTime);
/* Do something that takes up some time. For example sleep for 1.7 seconds. */
Thread.Sleep(1700);
/* Read the end time. */
DateTime stopTime = DateTime.Now;
Console.WriteLine(stopTime);
/* Compute the duration between the initial and the end time. */
TimeSpan duration = stopTime - startTime;
Console.WriteLine(duration);

The output of this code looks something like this:


4/17/2005 4:12:30 PM
4/17/2005 4:12:31 PM
00:00:01.7224768

As we see, by default the time interval is printed in the format hh:mm:ss.msec. If we want to retrieve separately the number of hours, minutes, seconds or milliseconds, we can do it through the properties of the TimeSpan class. Look at the code below to see how to do this.


/* Read the initial time. */
DateTime startTime = DateTime.Now;
Console.WriteLine(startTime);
/* Do something that takes up some time. For example sleep for 1.7 seconds. */
Thread.Sleep(1700);
/* Read the end time. */
DateTime stopTime = DateTime.Now;
Console.WriteLine(stopTime);
/* Compute the duration between the initial and the end time. 
* Print out the number of elapsed hours, minutes, seconds and milliseconds. */
TimeSpan duration = stopTime - startTime;
Console.WriteLine("hours:" + duration.Hours);
Console.WriteLine("minutes:" + duration.Minutes);
Console.WriteLine("seconds:" + duration.Seconds);
Console.WriteLine("milliseconds:" + duration.Milliseconds);

The result of running this code is something like this:


4/17/2005 4:17:28 PM
4/17/2005 4:17:30 PM
hours:0
minutes:0
seconds:1
milliseconds:712



If we look more attentively, we will realize that this mode of retrieving the hours, minutes, seconds and milliseconds is not very useful. Because each field is returned separately and if we want to find out the total number of hours, minutes or seconds or milliseconds we have to manually sum up the individual fields.
Luckily, the TimeSpan class also provides some properties for directly retrieving the total elapsed hours, minutes, seconds and milliseconds. Look at the following code to see how these properties can be read.


/* Read the initial time. */
DateTime startTime = DateTime.Now;
Console.WriteLine(startTime);
/* Do something that takes up some time. For example sleep for 1.7 seconds. */
Thread.Sleep(1700);
/* Read the end time. */
DateTime stopTime = DateTime.Now;
Console.WriteLine(stopTime);
/* Compute the duration between the initial and the end time. 
* Print out the number of elapsed hours, minutes, seconds and milliseconds. */
TimeSpan duration = stopTime - startTime;
Console.WriteLine("hours:" + duration.TotalHours);
Console.WriteLine("minutes:" + duration.TotalMinutes);
Console.WriteLine("seconds:" + duration.TotalSeconds);
Console.WriteLine("milliseconds:" + duration.TotalMilliseconds);

The result of this code is something like:


4/17/2005 4:23:27 PM
4/17/2005 4:23:29 PM
hours:0.000475684
minutes:0.02854104
seconds:1.7124624
milliseconds:1712.4624

Which is indeed much more useful, isn't it?

More advanced operations on time intervals

C# allows more advanced operations on time intervals. For example we can compute the sum of two TimeSpan instances, and the result is also of TimeSpan type.
Look at the following code to see how we can measure two separate time intervals and then easily compute the total execution time.



/* Read the initial time. */
DateTime startTime1 = DateTime.Now;
/* Do something that takes up some time. For example sleep for 1.7 seconds. */
Thread.Sleep(1700);
/* Read the end time. */
DateTime stopTime1 = DateTime.Now;
/* Compute and print the duration of this first task. */
TimeSpan duration1 = stopTime1 - startTime1;
Console.WriteLine("First task duration: {0} milliseconds.", duration1.TotalMilliseconds);
/* Do something that does not have to be measured. 
* For example sleep for a while. */
Thread.Sleep(900);
/* Now we want to measure another task. We store the start time. */
DateTime startTime2 = DateTime.Now;
/* We perform the second task which again takes up some time.
* For example we can sleep for 2.1 seconds. */
Thread.Sleep(2100);
/* We store the end time of the second task. */
DateTime stopTime2 = DateTime.Now;
/* Compute and print the duration of this second task. */
TimeSpan duration2 = stopTime2 - startTime2;
Console.WriteLine("Second task duration: {0} milliseconds.", duration2.TotalMilliseconds);
/* Compute the total execution time. */
TimeSpan totalDuration = duration1 + duration2;
Console.WriteLine("Total duration: {0} milliseconds.", totalDuration.TotalMilliseconds);

The ouput obtained by running this code is:


First task duration: 1702.448 milliseconds.
Second task duration: 2103.024 milliseconds.
Total duration: 3805.472 milliseconds.

In the same manner we can compute the difference between two TimeSpan instances. Again the result will be of TimeSpan type.

Conclusions

As we could see, the combination of DateTime and TimeSpan classes is very powerfull. It allows us to very easily record the system time and then measure execution times. These two classes can save us a lot of headaches if we know about their existence.

вторник, 25 мая 2010 г.

Timer vs DispatcherTimer



Windows.Forms.Timer uses the windows forms message loop to process timer events. It should be used when writing timing events that are being used in Windows Forms applications, and you want the timer to fire on the main UI thread.
DispatcherTimer is the WPF timing mechanism. It should be used when you want to handle timing in a similar manner (although this isn't limited to a single thread - each thread has its own dispatcher) and you're using WPF. It fires the event on the same thread as the Dispatcher.


In general, WPF==DispatcherTimer and Windows Forms==Forms.Timer.
That being said, there is also System.Threading.Timer, which is a timer class that fires on a separate thread. This is good for purely numerical timing, where you're not trying to update the UI, etc.

вторник, 11 мая 2010 г.

HOWTO: Creating an Uninstall Shortcut for an InstallScript MSI Project



As a general rule, Microsoft expect you to uninstall MSI applications from the Add/Remove Programs tool in the Control Panel.
Sometimes however, its nice to add a Start->Programs Menu – ‘Uninstall Shortcut’ to facilitate this action, for user convenience.
The following post details adding such a shortcut to a simple MSI build in Visual Studio 2008.


Browse to the MSI project folder (using Windows Explorer), right click and select New->Shortcut from the context menu. In the Create Shortcut Wizard dialog that pops up type ‘%windir%\system32\msiexec.exe -x {prodCode} ‘ as the location of the shortcut, where prodCode is the Product Code of the MSI package.
create_shortcut_uninstallerproduct_code_uninstaller
This Product Code can be identified from the Project Properties of the MSI Project in Visual Studio. Also, provide a proper name for the shortcut (such as Uninstall “product”, where “product” is the name of the application) and click Finish.
The next step involves adding this shortcut to the User’s Programs Menu folder of the MSI project in Visual Studio. The problem is that files with extension .lnk (extension of the shortcut) cannot be added to the Project.
First we need to rename the shortcut extension from .lnk to .txt. Open up a DOS command window and browse to the location of the shortcut using the ‘cd’ command. Remember to Run as Administrator if you are using Vista!
command_rename_uninstalleruser_programs_uninstaller
Now type ‘ren uninstall.lnk uninstall.txt’ where “uninstall” is the name of the shortcut item. Simply add the renamed shortcut into the User’s Programs Menu folder of the MSI project in the same manner as you would add any other file (Right Click > Add > File). Then in Visual studio Rename the shortcut from .txt back to .lnk and your done.
Build the MSI project and the necessary setup files will be created in the bin folder of the project. Once run the uninstall shortcut will appear in the program menu.

суббота, 8 мая 2010 г.

Installing Windows SharePoint Services on Windows 7 / Vista



Windows SharePoint Services (WSS) is not supported on a client operating system, but that’s not to say it shouldn’t run – right? After all, Windows client releases include a web server and can run a database service – that should pretty much cover the basics (back in the days of Windows NT it was generally reckoned that the differences between the Workstation and Server releases were just a few registry entries – but even if that was true then, there are a few more differences today)! In response to this, the guys at Bamboo Nation came up with an installer for SharePoint on Vistaand, even though it’s been around for a while (thanks to Garry Martin for alerting me to this), last week I finally got around to trying it out on Windows 7.


It seems to work well but, having never installed SQL Server 2008 Express Edition (WSS needs access to a SQL database) I needed to combine two very good resources (the Jonas Nilsson’s installation guide for Windows SharePoint Services 3.0 SP1 on Windows Vista and Symantec’s article on installing and configuring SQL Server 2008 Express) – the result is my installation notes (repeated in full here in case either of those articles ever disappears but for screen shots, refer to the originals – or to Jim Parshall’s video tutorial):
  1. Gather together all the resources that will be required. Assuming that Windows is already running, the remaining components are:
  2. Install and configure SQL Server 2008 Express Edition:
    • SQL Express may be downloaded with or without tools – I went for the “without” option but the tools may be useful for troubleshooting purposes. If you’re installing on an older platform, there are some pre-requisites (.NET Framework 3.5 SP1Windows Installer 4.5 and Windows PowerShell 1.0) but my Windows 7 client already had these (or later versions).
    • Run the SQL Server Express installer and follow the wizard. It’s fairly straightforward but there are a couple of things to watch out for:
      • For the instance configuration, specify MSSQLSERVER as both the named instance and the instance ID.
      • For the server configuration, use NT AUTHORITY\SYSTEM (no password) as the SQL Server database engine account name and set the SQL Server Browser startup type to Automatic.
      • For database engine configuration, either Windows or mixed mode authentication may be used (I stuck with the defaults) but the installer will not continue until users or groups are specified for unrestricted access to the SQL server. SQL DBAs and security guys will probably have lots of best practice advice here for use with production servers but I took the view that it’s probably nothing too much to worry about on a developer workstation and simply gave the necessary rights to the account I was running as.
  3. Install and configure Internet Information Services in Control Panel, Programs and Features by clicking the option to turn Windows features on or off and enabling:
    • Internet Information Services
      • Web Management Services
        • IIS 6 Management Compatibility
          • IIS 6 Management Console
          • IIS 6 Scripting Tools
          • IIS 6 WMI Campatability
          • IIS 6 Metabase and IIS 6 configuration capability
        • IIS Management Console
      • World Wide Web Services
        • Application Development Features
          • .NET Extensibility
          • ASP.NET
          • ISAPI Extensions
          • ISAPI Filters
        • Common HTTP Features
          • Default Document
          • Directory Browsing
          • HTTP Errors
          • HTTP Redirection
          • Static Content
        • Health and Diagnostics
          • HTTP Logging
          • Request Monitor
        • Performance Features
          • HTTP Compression Dynamic
          • Static Content Compression
        • Security
          • Basic Authentication
          • Request Filtering
          • Windows Authentication
  4. Install the WSS on Vista setup helper application by running wssvista.msi.
  5. Install WSS by:
    • Locating the WSS on Vista helper application files in %programfiles%\WSSonVista\Setup and running setuplauncher.exe.
    • Pointing the setuphelper to the WSS installer (sharepoint.exe)
    • Following the WSS installation wizard, selecting an advanced installation for a web front-end server, creating a new server farm, and supplying the details for the local SQL database (including the account details).
  6. At the end of the WSS installation, take a note of the port number used, and then navigate to http://localhost:portnumber/. If all goes well, then you should see the SharePoint Central Administration site in your browser:
    Windows SharePoint Services running on Windows 7
Finally, a couple of additional notes:
  • I ran all of this as a standard user, answering just a few UAC prompts at the appropriate points to elevate my privileges).
  • These instructions will allow access to SharePoint site from the local machine; however it will be necessary to create some firewall exceptions if remote client access is required.

Hot to turn off the application compatibility engine in Windows 7



 To turn off the application compatibility engine you need to:
  1. Run GPEdit.msc
  2. This should open the Local Group Policy Editor
  3. In the tree (on the left) select Local Computer Policy then Computer Configuration,Administrative TemplatesWindows Components and finally Application Compatibility
  4. Locate the entry for Turn off Application Compatibility Engine and double click on it
  5. Select the Enabled radio button and then click OK
  6. Next locate the entry for Turn off Program Compatibility Assistant and double click on it
  7. Select the Enabled radio button and then click OK


You should now have something that looks like this:
picture3
Now you will need to reboot your computer (forcing a group policy update is not enough in this case).