devxlogo

Touring Whidbey’s Base Class Library Enhancements

Touring Whidbey’s Base Class Library Enhancements

he Base Class Libraries were first introduced as a core component of the .NET Framework back in January 2002. The introduction of the BCL represented a huge step forward in simplicity and consistency of API design for application development. Through provision of a standard hierarchical design known as namespaces, the BCL removed many of the downsides but did not eliminate all of the need for leveraging unmanaged or third-party APIs.

The .NET Framework 1.0/1.1 provided a BCL set that can be segmented into three functionality groups: a managed group, a managed wrappers group, and a support services group. The managed group contains classes consisting mostly of managed code implementations that replace unmanaged APIs. A perfect example of this is ADO.NET found in System.Data. The second group consists of managed wrappers around code or services still implemented as unmanaged code. An example of this can be found in the System.EnterpriseServices namespace that exposes COM+ Services to managed classes. The final functionality group provides support services to facilitate interoperability between the managed and unmanaged APIs. Many of these classes can be found in System.Runtime.InteropServices.

Many of the enhancements to the Whidbey BCL set focus on the managed group of classes. Although the interoperability support provided by the BCL allows seamless use of unmanaged code, providing similar functionality as true managed classes improves the performance, general ease of use, and reduces the dependency on proper installation of the underlying unmanaged code being replaced.

Fast Facts
Enhancements to the Base Class Library provide sought-after functionality missing from the .NET Framework 1.1, including simplified DPAPI-based encryption classes and significant increases in Console class functionality.

The Whidbey BCL offers new classes as well as new features for existing BCL classes that greatly simplify a number of common tasks. Some of these new classes can be considered information classes, designed to facilitate information acquisition. Some BCL enhancements provide improved network support or network-oriented features. Other BCL enhancements offer completely new functionality, some of which I’ll describe below.

I can’t cover all the changes to the BCL in this short space; I will cover some of the more important or noticeable areas of improvements. My article discusses the alpha version of the Whidbey BCL, which will continue to evolve, improve, and change as Microsoft moves through the alpha and beta process.

New Classes
Many of the new Whidbey BCL classes provide functionality directly through the .NET Framework that were previously available to developers only through COM interoperability and/or third-party APIs, or functionality that could be obtained through substantially less convenient avenues.

Obtaining Drive Information
One new BCL enhancement, the DriveInfo class which you’ll find in the System.IO namespace, provides functionality similar to the FileInfo and DirectoryInfo classes already found in the System.IO namespace. DriveInfo provides methods and properties to query information about a current drive on the system or, through the shared GetDrives method, retrieves an array of DriveInfo objects representing all the logical drive names on a computer. Developers will typically use this class to determine available size, or total size, as shown in Figure 1, or to determine whether a drive is a hard disk, network share, or floppy drive. To retrieve information about the “C” drive, you could use code similar to the following:

   Dim c As New DriveInfo("C")   Console.WriteLine("Data for Drive C:")   Console.WriteLine("Avail: {0} bytes", _         c.AvailableFreeSpace)   Console.WriteLine("Total Free: {0} bytes", _      c.TotalFreeSpace)   Console.WriteLine("Format: {0}", c.DriveFormat)   Console.WriteLine("Type: {0}", c.DriveType)   Console.WriteLine("Name: {0}", c.Name)   Console.WriteLine("Size: {0}", c.TotalSize)   Console.WriteLine("Label: {0}", c.VolumeLabel)
Obtaining Configuration Details
Enhancements to the BCL provide options for retrieving and updating configuration information from managed code. The Configuration class, found in the System.Configuration namespace, provides the ability to easily retrieve machine configuration information. Much of the System.Configuration namespace is contained in the System.dll assembly, but the Configuration class is contained within System.Web.dll. If you want to retrieve connection string information, in particular, from the new configuration schema element, new features to the ConfigurationSettings class are an easier route to follow. For example:
   Dim config As Configuration = _      Configuration.GetMachineConfiguration( _                                          "localhost")   Dim section As ConfigurationSection = _      config.Sections("connectionStrings")   Dim node As XmlNode = section.GetRawXml      ' Simpler route using ConfigurationSettings   Dim conn As String = _      ConfigurationSettings.ConnectionStrings. _                                        Item("c1")

Tracing to the Console
The Trace class provides a standard process for tracing code executing application instrumentation. BCL enhancements include a new ConsoleTraceListener class that joins the existing DefaultTraceListener, EventLogTraceListener and TextWriterTraceListener classes. The ConsoleTraceListener class abstracts the process of sending tracing statements to a console. This simplifies the process of including the console as a destination for trace messages by eliminating the need to write a custom listener to accomplish this goal. In the following code snippet, I’ll add a new instance of the ConsoleTraceListener to the Listeners collection:

   Sub SetUpListener()     Trace.Listeners.Clear()     Trace.Listeners.Add(New ConsoleTraceListener)     Trace.WriteLine("Console Listener initiated")   End Sub

Timing Code Execution
Timing code execution from a non-arbitrary point A to another point B in code has never been a difficult thing to accomplish. On the other hand, the .NET Framework did not simplify this task. The BCL adds a Stopwatch class that provides methods and properties to accurately measure elapsed time.

The Stopwatch class provides all of the intuitive features you expect to find. Call the Start method to instruct the class to begin counting from the current elapsed time value. Do not start an already running Stopwatch, as it has no impact. Call the Stop method to end the current time measurement recording or to establish an interval time and pause the Stopwatch. Do not stop an already stopped Stopwatch, as it has no impact. Call the Start method again to resume time measurement recording. Call the Reset method to clear the cumulative elapsed time.

You can retrieve the elapsed time for a Stopwatch instance by checking the Elapsed, ElapsedTicks, or ElapsedMilliseconds properties. You can call ElapsedTicks to retrieve a raw indicator of elapsed units or use the Frequency field to determine the relationship between ticks and actual elapsed time in direct terms such as milliseconds.

A tick is the smallest unit a Stopwatch measures. A Stopwatch tick is not the same as a System.Ticks value. A System.Ticks value represents a 100-nanosecond span. A Stopwatch tick represents a time interval equal to one second divided by the value of the Frequency field. For example, a high-frequency timer, such as that shown in Figure 3, has a Frequency value in the millions, providing sub-millisecond elapsed time resolution granularity. Support of the hardware and OS is required for the underlying timing mechanism to provide high-resolution. Check IsHighResolution to determine whether the Stopwatch supports high-resolution elapsed time intervals.

Existing Class Enhancements
Not all the enhancements to the BCL are implemented as entirely new classes. After much feedback from clients, Microsoft has started to insert many highly desired improvements to existing BCL classes.

Simplified File Reading and Writing
Reading and writing to a file is easy to accomplish, but certain file access scenarios are not as simplified as they should be. Prior to Whidbey, file access for reading or writing typically involved instantiating a FileStream object with the desired access mode, reading or writing a byte array to or from the file, and then closing the FileStream object. If the file contents consisted of text, the byte array needed to be converted, adding another step. Alternatively, the FileInfo class provided methods to create StreamReader and StreamWriter classes allowing the direct reading or writing of text. Using a FileInfo class and StreamReader or StreamWriter classes added extra steps to the process.

In Whidbey, the File class gains several shared methods designed to simplify file access. Previously, the File class was used indirectly to access files by providing methods to create FileStream, StreamReader, or StreamWriter classes that perform the actual file manipulations. The File class is now enhanced with six new methods that directly manipulate file contents in a single method call.

  • ReadAll
  • ReadAllBytes
  • ReadAllLines
  • WriteAll
  • WriteAllBytes
  • WriteAllLines

All six methods open the file specified by a path parameter, read or write the data involved, and then close the file. The write methods create the file and overwrite the file if it already exists. The ReadAll and WriteAll methods operate on a single string, ReadAllBytes and WriteAllBytes operate on byte arrays, and ReadAllLines and WriteAllLines interact with an array of strings. In the following code snippet, the WriteAllLines method is used to write a string array directly to a file with a single method call:

   Sub SimplifiedFileAccess()   Dim lines(3) As String       lines(0) = "This"       lines(1) = "     is"       lines(2) = "        demo"       lines(3) = "             file"       File.WriteAllLines("c:File.txt", lines)       Console.Write(File.ReadAll("c:File.txt"))   End Sub

Improving Graphics Performance
The new BufferedGraphics class provided in the BCL is intended for manual double buffering scenarios where manual coding and control is desired. For general-purpose double buffering needs, the easiest route to leverage double buffering for Windows Forms or custom controls is built into the Control class found in the System.Windows.Forms namespace. In prior versions of the BCL, double buffering was enabled for controls by using the SetStyle method of the Control class to set the style bit to True for three different styles.

  • ControlStyles.AllPaintingInWmPaint
  • ControlStyles.DoubleBuffer
  • ControlStyles.UserPaint

Double buffering is now simplified and optimized. The Control class provides a new DoubleBuffered property and the existing SetStyle method is used to set a new style bit of the Control class called OptimizedDoubleBuffering. Set either of these values to True to implement the same behavior as setting the style bits separately for both AllPaintingInWmPaint and UserPaint to True. The existing DoubleBuffer style bit is now deprecated. The OptimizedDoubleBuffering style behavior redirects all painting operations for the control through a default graphics buffering, greatly reducing flickering without additional code required.

Not Your Grandpa’s Console
The BCL class that gains the most new features is the Console class. Prior to the new features, the Console class allowed limited input and output buffer access, and interactions limited to very linear scenarios. Reading and writing task interactions with the screen buffer were dictated by the simple Read, Write, ReadLine, and WriteLine methods.

Enhancements to the Console class enable complete control over positioning of the cursor, foreground and background colors, and the ability to move sections of text, including color scheme, around the screen buffer. Moving text around the screen buffer eliminates the need to manually reconstruct the information in the screen buffer at the new location. The new properties supported by the Console class, shown in Table 3, allow extensive abilities to manipulate the buffer screen characteristics. The possible color choices have been expand to 16 choices.

Table 3: Numerous new Console class properties provide significantly enhanced features for console-based applications.

Console Property name

Description

BackgroundColor

Modifies the background color of the console

BufferHeight

Gets the current height of the buffer area

BufferWidth

Gets the current width of the buffer area

CursorLeft

Gets the current column position of the cursor

CursorSize

Modifies the current size of the cursor

CursorTop

Gets the current row position of the cursor

CursorVisible

Modifies whether the cursor is visible

ForegroundColor

Modifies the foreground color of the console

KeyAvailable

Indicates whether a key has been pressed

Title

Modifies the title of the console title bar

TreatControlCAsInput

Modifies whether (CTRL+C) is treated as ordinary user input to be processed by the Console class or handled by the operating system as a program execution interruption. If set to False, the CancelKeyPress event can be used to process (CTRL+C).

WindowHeight

Gets the current height of the console window area

WindowLeft

Gets the current leftmost position of the console window area relative to the screen buffer

WindowTop

Gets the current top position of the console window area relative to the screen buffer

WindowWidth

Gets the current width of the console window

The Console class gains numerous methods and a new event. You can call the Beep method to issue a system beep. You can call the Clear method to move the cursor to the upper-left corner and clear the screen buffer using the current values of the ForegroundColor and BackgroundColor properties. Call the ResetColor method to revert back to the default console color scheme. You can call the SetBufferSize method to programmatically control the size of the screen buffer and call MoveBufferArea to reallocate characters and their current color scheme from one section of the screen buffer to another without manually reconstructing the screen buffer section affected. You use a combination of the KeyAvailable property and the ReadKey method to grab user input character by character without blocking the executing thread. You handle the CancelKeyPress event to perform complex logic in response to the user typing Ctrl-C.

The enhancements to the Console class provide significantly increased options for developing highly interactive console-based applications that are far more visually appealing than the traditional console-based application. These applications don’t have the overhead associated with moving to a full-blown graphical-based user interface provided by Windows Forms-based applications.

An example of many of these features in action together is shown in Figure 4, and the complete code listing is in Listing 1.

Managed Support for FTP
Support for issuing numerous types of network requests was provided by version 1.0 of the .NET Framework and the Base Class Libraries. A somewhat obviously missing feature from this network support involved the complete lack of a direct managed class for issuing FTP requests. This oversight is fixed in the Whidbey BCL. The FtpWebRequest class represents a basic FTP interface for issuing requests. The existing WebClient class now also supports the FTP protocol.

Use the Create method of the WebRequest class to obtain an instance of FtpWebRequest. A valid user name and password are required and should be wrapped in a NetworkCredentials class and assigned to the Credentials property of the FtpWebRequest instance. The specific FTP command to issue is controlled by setting the Methods property to one of the values of the FtpMethods structure as follows:

  • AppendFile
  • DeleteFile
  • DownloadFile
  • GetFileSize
  • ListDirectory
  • UploadFile

The return value of an FTP request should be obtained by calling the GetResponseStream method to obtain an instance of the FtpWebResponse class, as shown below:

   Const file As String = "ftp://.../Demofile.txt"   Dim ftpReq As FtpWebRequest = _       WebRequest.Create(file)   ftpReq.Method = FtpMethods.DownloadFile   ftpReq.Credentials = New NetworkCredential( _         "anonymous", "demopwd")   Dim ftpResp As FtpWebResponse    ftpResp = ftpReq.GetResponse   Dim ftpRespStream As Stream   Dim reader As StreamReader   ftpRespStream = ftpResp.GetResponseStream   reader = New IO.StreamReader(ftpRespStream, _      System.Text.Encoding.UTF8)   Console.WriteLine(reader.ReadToEnd)

The simplest approach to downloading files from an FTP server is provided by the new file transfer protocol supported by the WebClient class. Use the DownloadFile method to issue an FTP request for a file and save it immediately to a file on the local file system, as shown below:

   Dim client As New WebClient   Dim reader As StreamReader   client.Credentials = New NetworkCredential( _      "anonymous", "demopwd")   client.DownloadFile(TargetFile, "C:Demofile.txt")

If the destination for a file to be downloaded from an FTP server is not the local file system but the current process, use the DownloadData method of WebClient to retrieve file contents directly, as shown below:

   Const target As String = "ftp://.../Demofile.txt"   Dim client As New WebClient   Dim reader As StreamReader   'This example assumes anonymous logon.   client.Credentials = New NetworkCredential( _       "anonymous", "demopwd")   Dim destFile As String    destFile =  Encoding.UTF8.GetString( _      ftpClient.DownloadData(target))   Console.WriteLine(destFile)

The Base Class Libraries provide the basic foundation for just about every task an application needs to perform. The process of creating a standardized set of consistent application programming interfaces includes the inevitable burden of keeping up with the expectations of the developer community. The task undertaken by the Framework team at Microsoft to craft a collection of APIs that could simultaneously serve as the foundation for a whole new generation of applications, provide a bridge between the Framework and its predecessor (COM), and unite and satisfy the demands of hard core developers from the Visual Basic, C++, and third-party language camps is substantial. The only task that could conceivably be more difficult might be to improve substantially on this set of Base Class Libraries.

Although I can only cover a fraction of the changes appearing in the Whidbey BCL here, the changes I did cover should show that significant additions and enhancements to the Base Class Libraries are forthcoming. You can assume that many things will change as the Framework team moves forward into the Beta stages. New features will surface, additional enhancements will be fleshed out and completed, and odds are, maybe even a feature or two will be cut back or removed.

If you step back for a second and look at the enhancements already showing up in the alpha build of Whidbey, you should feel very confident. Given this first look at Whidbey, the future of .NET and the future of application development as a whole seems very strong.

devxblackblue

About Our Editorial Process

At DevX, we’re dedicated to tech entrepreneurship. Our team closely follows industry shifts, new products, AI breakthroughs, technology trends, and funding announcements. Articles undergo thorough editing to ensure accuracy and clarity, reflecting DevX’s style and supporting entrepreneurs in the tech sphere.

See our full editorial policy.

About Our Journalist