Article Author: Simon Robinson
Introduction
This is a Summary of the talk: DEV322: .NET Framework: What’s New in the Framework for V2.0, by David Platt (of Rolling Thunder Computing), Thursday 7 July 2005.

Figure 1. The DEV322 talk, presented by David Platt
Please bear in mind when reading this that I’ve put the TechEd reports together based on notes made and photos taken during each talk. I’ve tried as far as possible to stick to what the speaker has said but it’s inevitable that I’m going to have misremembered or misunderstood a few things, so don’t expect 100% accuracy. (And don’t expect photos, where provided, to have the same quality as real screenshots!). In cases where I wanted to add thoughts of my own, I’ve normally done so in italics.
A talk and a written report are two different things with different requirements. In order to make the article easily readable I’ll have extensively paraphrased the speaker’s comments; I may have added my own headers, or swapped the order of some material. In some cases I’ve omitted material that is not appropriate for the typical ASP Today readership.
The Console
Support for the console is much improved, for example the cursor is directly addressable.
As an example, does anyone remember Space Invaders? After asking this question David demonstrated a working space invaders game – shown in Figure 2. The game is of course written entirely in C# using .NET 2.0.

Figure 2. A managed space invaders game
Threading
There is now a managed semaphore object.
Networking
Most computing involves networking these days – very few people write applications that sit on one machine and never interact with a network. There are accordingly quite a few improvments to networking support. New support exists for:
- The Serial port – via a new SerialPort type. The SerialPort class works a bit like a stream; you can control aspects such as the baud rate.
- The FTP protocol
- Network Information – you can get obtain information about your network – this is mostly via the new System.Net.NetworkInformation class
As an example David demonstrated calling ping from the command line. Except it wasn’t the usual ping utility, it was a program he’d written in C#! Figure 3 shows a sample of code that uses the new Ping class that supports this.

Figure 3. Using Ping
Running on 64-Bit Machines
In general, if you build a 32-bit application will it work on 64-bit machines – that’s nothing to do with .NET 2.0, it should work by default. Microsoft have been working on the issue of running existing 32-bit software in an age of 64-bit machines, and the solution they have adopted is pretty similar to the technique they used for for 16 bit – 32 bit transition: An environment that hosts old-style code. The objective is that that running 32-bit code should seemlessly work. In fact the transition from 16 to 32 bits was very big change – eg. bringing in a different memory addressing system. The changes involved in moving to 64-bit architectures are much smaller so we can expect even fewer problems this time.
Having said all that, .NET 2.0 code will JIT-compile to 32- or 64-bit code as appropriate removing the need for a hosting environment, but there will be an option to restrict your assemblies to run only on either one of the platforms if you wish. .NET 1.x will only JIT as a 32-bit application, which must be hosted to run on a 64-bit machine. Incidentally Visual Studio is 32-bit application.
Performance
The pre-JITter, NGen, has considerably improved (frankly, it wasn’t that good in .NET 1.x).
There are also other improvements, as listed in Figure 4.

Figure 4. Some of the claimed .NET 2.0 performance improvements
As an aside, David quoted what he referred to as Rushes law: ‘It doesn’t matter how good the hardware is because the software boys will piss it away.’ In other words, he can virtually guarantee that any performance improvements in .NET 2.0 will quickly disappear – the people writing .NET 2.0 applications will quickly find new cool things to eat up those extra CPU cycles.
Generics
Microsoft is aiming for first class support for generics, which will allow you to parameterize the type for strongly-typed arrays. Generics means that if you wanted to create a variable size array of – say – int s, then in .NET 1.x you’d have declared the collection as
ArrayList myList = new ArrayList();
Whereas in .NET 2.0 you’d write
List<int> myList = new List<int>();
The benefits of the new approach are:
- No need to box value types. This is because List<> knows it’ll be storing integers and so knows how much space to allocate.
- You get a compile-time, rather than a run-time, error if you try to store the wrong type in a generic collection.
- There is no need to cast to the appropriate type when retrieving values.
A theme this leads into is that generics makes it easier to write good code and harder to write bad code. (Plug: David is currently writing a book, Why Software Sucks , which argues for need to go to next level in software coding quality, and that the way software is often coded today is simply not good enough).
Besides their use in collections, two other places to look out generics are event handlers and nullable types:
- EventHandler<T> saves you from having to define your own event handler delegate types.
- Nullable<T> is useful in situations where you need to allow null as a value for value types.
C++
David mentioned that he believed the new C++ compiler is miles better than old one. He didn’t give any specific details but reminded us as evidence that Microsoft had hired Stanley Lippman to the C++ team.
Security
Security is vitally important – it’s pretty much the first thing anyone has to think about in today’s world – so it’s encumbant on us as developers to always write inherently safe code.
Improvements in security support include:
- You don’t need to drop to the Win32 API as much when dealing with X509 certificates or XML encryption – the support is now there in the Framework.
- There is a new data protection API. This means, amongst other things, that you can now encrypt file contents with just one or two lines of code.
- There is new support for access control lists (ACLs)
As another aside, David mentioned he’d coined a so-called Platt’s 3rd law: "Laziness trumps everything." That has the corollory that we need to make the smart things easy to do and the dumb things hard to do. The relevence is that in .NET 2.0, security has got easier to do so – that’s good because it means developers will more often write code that is secure.
The SecureString Class
There is a new class, System.Security.SecureString . To understand the purpose of this class, think about eg. a password. You probably never want anyone to see the password, but if you store it in a simple System.String instance there are some security risks. For example, how do you get rid of the value when you’ve finished with the string? You can set the reference to the string to null , but the value itself is still in the managed heap. Indeed there may be several copies of it lurking around if the garbage collector has moved it during previous collections. Bluntly, the heap was never designed to guard against someone going through it with a memory dump tool. SecureString solves this kind of issue.
Assigning a value to secure string is pretty simple and just like assigning a value to a string, eg:
SecureString password = new SecureString();
password = "blah";
The value is stored in an encrypted form, and SecureString also has a Clear() method that completely wipes out the data. Extracting the value from a secure string is possible but complicated – and not often done.
Error Reporting
The error reporting service involves the familiar dialog box that comes up when a program crashes and asks if you want to report the fault to Microsoft. This service is now available to your programs. ( Simon adds: David didn’t specify too much how the service is available so I’m not clear if he means there’s some API through which you can programmatically invoke the service. However he did mention in another talk that it is possible to register register with the Microsoft error reporting service and hence be able to view details of reported errors that result from your own applications, with a stack trace that helps you debug common errors. He also mentioned that the error reporting service has been tremendously useful in helping Microsoft to make Windows more stable. ).
The relevence to security here is that this all means that memory dumps may be sent to your administrators and to Microsoft. Another reason for using SecureString for sensitive information.
Security Exceptions
Security exceptions now give you much more information to help you pinpoint the source of errors – this information was much lacking in .NET 1.x.
Restricted Permission Debugging
It is now possible to debug with the permissions of the target code-access-security zone of an application using the new Debug-In-Zone feature. The obvious scenario here concerns applications that will be delivered over the network and so are likely to typically run with a restricted set of permissions. Historically it’s been difficult to debug such programs because the Visual Studio debugger gets full trust. That meant you couldn’t debug an application the way it actually runs when shipped. That’s all changed – now you can set the debugger to debug with the privilege of a specified zone.
The Permission Calculator
There’s now a permission calculator that analyzes your code and works out which permissions it would need to run. It is aimed at the problem that – coding standards say you should ship your application with the lowest permission set required, but in practice it’s extremely tedious to work out manually what that permission set actually is.
The easiest way to bring up the permission calculator is via the project properties then the Security tab. Enable click once security settings, as shown in Figure 5.

Figure 5. Enabling Click Once security settings.
This figure has been reduced in size to fit in the text. To view the full image Click here
Figure 5 shows that you can select a zone against which to check the permissions – here David has selected the LocalIntranet zone. This means the permission calculator can indicate whether the permissions required would actually be available, thus alerting you to the need to resolve the issue if you code won’t have sufficient permissions. Unfortunately the permission calculator doesn’t have a particularly fine level of granularity – thus, it can tell that the file access permission is required, but it can’t distinguish, for example, that a program only needs read, not write, access, or that it only needs to access a specific file.
David did remark on one Interesting issue: He had tested the permission calculator against a simple do-almost-nothing C# Windows Forms application and then again against an application that was supposedly identical, but was written in VB. He found that the VB application asked for a lot more permissions than the C# one, including seemingly irrelevent ones – eg. it required reflection permission – just for almost the simplest possible VB Windows forms application. David indicated he’s not clear what the reason for this is but is chasing it up – and possibly it might indicate that VB and C# are not ‘the same language [other than syntax]’.
Incidentally you don’t have to use the permission calculator from within Visual Studio. It also exists as a command line utility, permcalc , which emits the results as an XML file.
Debugging
Edit and Continue is now available when debugging in Visual Studio. However not all edits are allowed, since some edits would be just too complex in terms of the effects on the compiled code. So for example you can add new private fields during an edit-and-continue, but you can’t remove a field or method (you may be able to comment out the implementation of a method though). Similarly you can’t edit generic classes. Also, serialization won’t recognize any new fields.
Out of Band Releases
There will be a Rotor version 2. Most new CLR features will be included, and it will have the same academic/hobbiest-friendly license. It should appear about 3-6 months post-Whidbey and will target multiple platforms.
Garbage Collection
A number of improvements have been made to the garbage collector (GC). The improvements focus mainly on a particular problem with the collector in 1.x: It only tracks the managed heap, but there might be lots of unmanaged objects that also consume a lot of memory. For example Bitmap exists effectively as a small managed wrapper around lots of unmanaged memory. That means the GC might fail to notice a collection is required because the managed heap contains little data, but this data actually wraps a huge amount of unmanaged resources.
The solution to this is a new method, AddMemoryPressure() . This method tells the GC to treat an object based not on its actual (managed) size, but instead as if it is a certain size, based on an int value passed to the method. Effectively, AddMemoryPressure() increases frequency of garbage collections, and you’ll need to fiddle around to find value for the int parameter for your particular situation.
Note that if an object calls this method, it’s important that its finalizer removes same amount of memory!
There is a new property on the GC which tells you how many collections have been performed – you can use this to tune your applications to run fewer GCs.
Microsoft has also added a HandleCollector . The motivation here is that the GC doesn’t specifically track scarce unmanaged objects – that is, objects such as handles for which a hard limit exists to how many such objects can exist. This can cause a problem if client code forgets to call Dispose() against any managed objects that are responsible for such unmanaged handles etc. The HandleCollector represents a way of saying to the GC that there is a scarce object involved, and therefore of forcing a collection. The idea is that you use the handle collector to increment a handle count in the constructor of relevent types, and decrement the count in the finalizor, when the scarce resource is released ( Simon adds: I think there was an implied: ‘and in the Dispose() method’ here ). The GC will notice the state of the handle collector and may invoke more garbage collections if the handle count is high. The great thing about this is that this approach doesn’t cause extra collections if the client code follows the rules and calls Dispose() appropriately. So it doesn’t penalize good programmers for actions of the bad ones!
Click Once Deployment
David didn’t say much about this but commented that he believes it changes balance of when you should deploy smart clients – in favour of using smart clients more often.

