The Microsoft .NET Framework Library

advertisement
.NET Framework Library
2
.NET Framework Library
Overview
Objectives
This modules provides an overview about various aspects
of the .NET framework libraries that are not covered
elsewhere in the Microsoft .NET Developer Tools
Readiness Kit.
.NET Framework Library
3
Section 1: Introduction
Section 1: Introduction
We will start our tour through the .NET Framework Library
by looking back at the status-quo of the Windows
development libraries and will then take a look at the
rationale for the .NET Framework library from there.
Looking Back
The Microsoft .NET Framework Library
4
.NET Framework Library
Section 1: Introduction
Looking Back
Language Dependent Runtime Libraries
In all of today’s development languages for the Windows
platform, we find runtime libraries that are dependent on
the development language that is used. When you want to
concatenate two strings, there is a special way of doing
that in Visual Basic, a special way to do that with the
standards C-Runtime library and yet another way to do
that with the C++ Standard Template Library.
In addition, while most of the native platform APIs are
easily accessible from C and C++, Visual Basic makes
that a lot harder and there are many libraries that cannot
be used with Visual Basic directly. These API holes are
typically plugged with third part ActiveX controls, which
not necessarily add value, but simply wrap APIs that are
not immediately accessible from Visual Basic.
In essence, this leads to a very inconsistent set of
functions and component methods across languages and
forces developers to relearn technology sets they already
know.
Discriminatory access to functionality
In addition, these language-by-language runtime libraries
are very discriminatory and have lead to a schism in the
developer community. Visual Basic developers are often
regarded as “no real programmers” by C++ developer,
since their tools do not provide the same level of control
as the C language family. Although that attitude is
certainly childish, it roots in the discriminatory access to
platform services, of which many cannot be directly used
from languages like Visual Basic.
.NET Framework Library
5
So, indeed, many advanced tasks do require the use of C
and C++, but not because lack of developer skills to
handle the platform complexity, but because their primary
work-tool will not give them that option.
Core functionality scattered all over Windows
However, even if it would, developers would (and must do
so today) have to seek their required functionality
throughout a plethora of different ActiveX controls, Win32
APIs, Server SDKs and even in Internet Explorer.
Although the documentation for most of the Microsoftsupplied APIs and components is (luckily) grouped nicely
in the MSDN Library, it is much less convenient to find
them and use or reference them. This can unfortunately
turn from a mere inconvenience into a sheer nightmare
when it comes to deployment.
6
.NET Framework Library
Section 1: Introduction
The .NET Framework Library
One-stop, well-organized class framework
Like some giant department store in the mid-Western
United States, the .NET Framework Library offers “onestop” shopping. In reality, it’s more like the legendary
library of Alexandria! Instead of books, the Framework
Library warehouses classes that offer both the knowledge
and means to “do things software.” The organization of
the library is based on namespaces, which are essentially
a means of categorizing and grouping logically or
functionally similar classes together.
The resulting
namespace hierarchy makes working with the Framework
intuitive, especially as the actual namespaces are so
logically names. For example, classes that offer services
and functionality most commonly needed elsewhere in the
library, and essentially make up the “base system”, are
contained in the “System” namespace.
Likewise,
classes that expose methods to work with data are found
in System.Data, while the user interface classes for Web
development are rooted in the System.Web.UI
namespace.
Microsoft has made an extraordinary effort to design and
implement the Framework Library, and .NET in general, in
as OS-independent a manner as possible. Microsoft, in
conjunction with Hewlett-Packard and Intel, has even
submitted an OS-independent subset to ECMA
(http://www.ecma.ch), the same organization that
standardized other Web technologies, such as the ECMA
standardization of JScript, known as ECMAScript (ECMA262). The subset submitted for standardization includes
most things covered here (form more information refer to
http://msdn.microsoft.com/net/ecma).
.NET Framework Library
7
Integrates all current Windows technologies
The .NET Framework Library successfully integrates all
current Windows technologies; everything is in one place
and for all languages! You will find support for: Windows
Forms, the .NET means of creating forms based
applications; GDI+, the next iteration of GDI; support for
printing; Web Forms, a means of developing Web based
applications using a forms based paradigm; Web services;
networking support; and support for Active Directory,
WMI, MSMQ, Services, and more.
8
.NET Framework Library
Section 2: The System Namespace
Section 2: The System Namespace
As you learned, the System namespace is a foundation of
the .NET Framework library. While it is not technically the
“root” of the Library namespace hierarchy (there actually
is none), it is conceptually, as it provides the classes that
are most common to the library as a whole.
You will learn more about the classes found in the System
namespace as you read on, as well as other Framework
Library namespaces. Some topics you can expect to
learn about are:
System.Object
The not-so-primitive "primitive" types
String and text classes
Dates, times and calendars
System console support
.NET Framework Library
9
Section 2: The System Namespace
The Root of Everything .NET: Object
Base class for each and every type
In the .NET Framework, everything is an object –
including even the simple data types, as you will learn.
The granddaddy of them all, or root to this object
hierarchy, is the Object class (a.k.a. System.Object). In
fact, inheritance from System.Object is typically implicit.
As you will find, all data types – both simple and complex
– share this same base class helping make their behavior
and the ways you use them consistent.
Single base-class makes framework consistent
This “object consistency“, if you will, is what helps makes
the Framework itself consistent. System.Object enables
you to use the collection classes of the Framework for
everything. It also provides an intrinsic model for handling
variant types that make programming less error prone,
especially when compared to using COM’s VARIANT
type. These positive affects are in a large part due to the
strongly typed nature of the Framework Library and the
exclusion of pointers and structures,
System.Object is a reference type
Value types (internally) inherit from ValueType
While System.Object is a reference type, the value types
found in the Framework are inherited not directly from
Object but from the ValueType class. System.ValueType,
however, is itself directly derived from Object, but
overrides certain virtual methods, etc in a manner that
makes the behavior of value types more logical – and
practical.
10
.NET Framework Library
Section 2: The System Namespace
System.Object's Methods (1/2)
Let us examine the six methods System.Object provides:
Equals();
Finalize();
GetHashCode();
GetType();
MemberwiseClone(); and ToString().
bool System.Object.Equals(Object o)
The Equal() method is used to test if an object is the same
instance as another object. In other words, if you have an
object A and an object B and you wish to see if they are
the same exact instance – reference the same object
instance – then you use the Equal method.
For value types, this method is overridden to test for value
identity (i.e. that two objects are of the same type and
represent the same value).
void System.Object.Finalize()
By default the Finalize method does nothing. It is meant
to be overridden by subclasses that wish to perform some
type of cleanup before the Garbage Collector (GC)
reclaims the Object. Note that the Finalize is not called
until the object is garbage collected but it is not
guaranteed to be run and if it runs it is not guaranteed to
be run at any specific time.
int System.Object.GetHashCode()
Essentially, this method generates a hash value for the
object that may then be used in any arbitrary hashing
algorithm (or other manner), for example in a hash table
(i.e. System.Collections.HashTable uses this method). It
is recommended that you override the method to return
good hashes; good hash distribution speeds up hash
tables. Incidentally, the default implementation is Identitybased hashing.
.NET Framework Library
11
Section 2: The System Namespace
System.Object's Methods (2/2)
System.Type System.Object.GetType()
Conceptually, GetType returns the object’s type. In
reality, it retrieves the Type object (System.Type) for the
object's class. System.Type is an abstract class that is
used to represent type declarations and provides the
primary means to access metadata and acts is the entry
point for .NET Reflection.
System.Object System.Object.MemberwiseClone()
MemberwiseClone() works through Reflection with any
class to provide a means to creates a exact clone (copy)
of "this" object. The method cannot be overriden.
System.String ToString()
The ToString method is designed to return a text
representation of the current object. The default behavior
is to return the fully qualified name of the class, but is
designed to overriden so that you can return information
more pertinent to your needs. This method is not
designed for user messages, although it can be helpful
when debugging. If your aim is user messages, use the
IFormattable interface.
12
.NET Framework Library
Section 2: The System Namespace
The "Primitive" Types
Traditionally perceived as "magic" or "special"
Traditionally, primitive types, such as integers, have been
perceived as “magic“. Indeed, in some object-oriented
languages, such as Java, primitives are all but magic in
that they are not objects themselves but more like a sheep
in a wolf’s skin – they exhibit object-like behavior and
expose means to work with them as if they were objects
but they are not. In .NET, however, all is an object – that
means that primitives are objects too. Actually, it is a very
SmallTalk-like model in which "primitive" types are regular
framework types.
However, still exposed as language-intrinsic types
While types in .NET are objects, the Framework still
exposes the types as language-intrinsic types.
For
example, if you use C# you work with the following types:
bool, int, long, string, double, float, etc. However, if you
program in Visual Basic.NET, the Framework exposes the
following types to you: Boolean, Integer, String, etc.
"Primitives" are mostly value-types
Although primitives are value-types, There is always an
exception to every rule. With primitive types it is that all
primitives are value-types except for System.String, which
happens to be a reference type.
"Primitive" Types are not so primitive anymore
One major feature the Framework designers built in when
they decided to make everything an object is that
primitives are not so primitive anymore; they are fullfeatured classes with rich functionality!
.NET Framework Library
13
Section 2: The System Namespace
Integer Numerics
The first stop on your journey down the primitives road is
at the numeric types, beginning with integers.
System.Int16, System.Int32, System.Int64
There are three types of integer types in the Framework:
System.Int16; System.Int32; and System.Int64. As per
the definition of an integer, these classes are used to
contain and work with standard integer (whole number)
types of varying magnitude (or length). While Int32
typically maps to the default language-mapped integer,
there is also an Int16 and Int64 of 16-bit and 64-bit length
respectively. The highest bit on all Int types is used as the
sign bit.
There are several framework interfaces implemented for
integers:



IFormattable: locale specific text formatting
IConvertible: standard conversion into other core types
IComparable: standard value-comparison with other
objects
The integers also benefit from the Parse() method, which
provides rich from-text conversions.
System.UInt16, System.UInt32, System.UInt64
The unsigned equivalents of Int16, Int32 and Int64 are:
UInt16, UInt32 and UInt64.
14
.NET Framework Library
Section 2: The System Namespace
Floating Point Numerics (1/3)
System.Single, System.Double
Next stop on your numeric tour are the floating-point
numbers: System.Single and System.Double. Both of
these primitive types are based on the IEEE 754 floating
point numbers used in most common programming
languages. Internally the values are represented as
fractions (narrowed values).
Designed for scientific/technical and technical purposes,
these types are not meant to represent business
numerals, such as monetary values.


System.Single: Single precision, 32-bit
System.Double: Double precision, 64-bit
Both types derive from the following interfaces:



Formattable: Functionality to format the value of an
object with local support; provides formatting that is
usable by the end-user.
IComparable: Generalized comparison interface, which
is implemented by types that may be ordered.
IConvertible: Describes a generalized type conversion
and convenience methods. For example, converting
an integer type to a string type.
.NET Framework Library
15
Section 2: The System Namespace
Floating Point Numerics (2/3)
System.Decimal
System.Decimal is designed for business numerals.
Because of its 128-bit size, of which 28 bits are significant,
it is ideal for large monetary amounts or other possibly
large or precision sensitive values. To be more precise,
the
range
of
possible
values
is
negative
79,228,162,514,264,337,593,543,950,335
through
positive 79,228,162,514,264,337,593,543,950,335!
Like their floating-point brethren Single and Double, the
Decimal types implement the IFormattable, IComparable,
and IConvertible interfaces.
There are a few “special features” specific to the Single
and Double types verses the Decimal type.
System.Double, System.Single specials:
Single and Double, for instance, support positive and
negative infinity using the PositiveInfinity and
NegativeInfinity constants on the class. Furthermore, both
these types can represent not-a-number (NaN) values by
using the NaN constant on class. Note that NaN always
compares false.
16
.NET Framework Library
Section 2: The System Namespace
Floating Point Numerics (3/3)
System.Decimal specials:
Decimal, on the other hand, cannot represent NAN or
infinity.
However, it has static value manipulation
methods such as Abs(d) and Negate(d) for getting the
absolute value or the negated value of a decimal
respectively.
It also exposes the following methods:



Truncate(d): Returns only the digits before the
decimal.
Floor(d): Rounds a decimal d to the next lowest whole
number.
Round(d,n): Rounds the decimal d to a specified
number of decimal places n. The value of n must be
between 0 and 28.
Decimal also has several static arithmetic methods for
performing math on two Decimal objects d1 and d2:
Add(d1,d2),
Multiply(d1,d2),
Subtract(d1,d2),
Divide(d1,d2), and Mod(d1,d2).
All equivalent operators are defined for the class.
.NET Framework Library
17
Section 2: The System Namespace
Doing Numerics: System.Math
What good would numerics be without math? The System
namespace contains a class dedicated to common
mathematical operations: System.Math.
System.Math class mainly supports IEEE types
Some operations for all numerics
While System.Math is designed to mainly support IEEE
types (i.e. floating or decimal numbers), it also provides
methods that are common to all numbers:



Abs(): Returns the absolute value of a number
Log(): Returns the natural logarithm of a number
Max(): Performs a comparison on two numbers, a and
b, and returns the greater of the two.
 Min(): Converse of Max().
 Round(): Rounds a number to the nearest specified
parameter.
 Sign(): Returns the sign of a number.
Operations:
You may find it more interesting to view some of the
operations grouped by “type”:




Trigonometry: Sin(),Cos(), Tan(), Acos(), Asin(), ...
Powers and Logarithms: Pow(), Log(), Sqrt(), ...
Extremes: Min(), Max()
Rouning: Floor(), Ceil(), Rint(), Round()
18
.NET Framework Library
Section 2: The System Namespace
System.String
System.String is the cross-language string
No framework would be complete without a string type,
and .NET provides one with little left to desire!
System.String is the cross-language string; it utilizes one
storage method and exposes one API aimed at creating a
unified means of handling strings! String is also localeaware and always Unicode.
Fully-featured string handling capabilities
String is a full-featured string class. It has methods to
perform forward and reverse sub-string searches:
IndexOf(), LastIndexOf(), StartsWith(), EndsWith(). It has
methods to either strip or pad a string with white space
(Trim(), PadLeft(), PadRight()), provides methods for
range manipulation and extraction (Insert(), Remove(),
Replace(), Substring(), Join(), Split()) and even ebables
you to perform character casing and advanced formatting
using ToLower(), ToUpper() and Format().
It is worth noting that the Format() method is much like C's
printf but safe.
.NET Framework Library
19
Section 2: The System Namespace
More Strings: System.Text Namespace
Although we are touring the System namespace, having
encountered the String class it makes sense to take a
short detour a string (or text) related namespace for a
moment. The System.Text namespace contains classes
representing various character encoding and conversions
as well as providing helper classes for manipulating String
objects and text in general.
StringBuilder
The StringBuilder class is a helper class that may be used
in conjunction with a String object to manipulate a string.
Because the StringBuilder uses a single buffer when
manipulating a string, it is a super-efficient class for
assembling large strings. String, in contrast performs
copy operations when assembling a string from multiple
literals or String objects.
Encoders and Decoders
Classes to represent and support character encoding and
conversions including ASCII, UTF-8, UTF-7, and Windows
Codepages. Some of the encoding/decoding supported
include:



The Unicode encoder for full UTF-16 compliant
streams
Encoder can write and decoder detect byte-order
marks
Supports big-endian and little-endian Unicode
encoding
20
.NET Framework Library
Section 2: The System Namespace
Other Core Types
System.Byte, System.SByte – Single byte numeric
Some other types that are core to the Framework include
System.Byte, which represents an 8-bit unsigned integer
and provides an object representation of a byte primitive.
Byte can contain an integer value in the range of 0-255.
In contrast SByte is not compliant with the common
language specification and may contain an integer value
in the range of –128 to 127.
System.Char – Single Unicode character
System.Char represents a single Unicode character.
System.Boolean – True or False logical value
System.Boolean is the object representation of a Boolean
value and contains the value of either true or false.
System.Guid
Windows programmers are familiar with GUID types. The
Framework provides a class that encompasses this 128bit, universally unique identifier. The class has a built-in
generator for new GUID values, System.Guid.NewGuid(),
and includes intrinsic support for converting to and from
strings.
The "Nothings"
“The nothings” are a special set of types:



System.DBNull: Database-equivalent NULL type
System.Empty: Like COM's VT_EMPTY
System.Missing: Used with optional args
.NET Framework Library
21
Section 2: The System Namespace
Date and Time Support
The Framework provides extensive support for dates and
times through its classes and namespaces.
System.DateTime class for dates and times
The DateTime class provides virtually unlimited date
values spanning 100 AD to 9999 AD and includes built in
arithmetics, such as AddDays() and AddSeconds().
DateTime is also sophisticated enough to contain localeaware formatting and parsing.
System.TimeSpan for durations
Because a period of time is intrinsically different than time,
the Framework provides the TimeSpan class. This class
can represent arbitrary time spans and do so using an
arbitrary unit by conversion.
System.TimeZone for time-zone support
Lastly, there is the TimeZone class, which is meant to
address the increased need to support multiple time
zones in solutions. It includes support for daylight saving
time.
22
.NET Framework Library
Section 2: The System Namespace
Date and Time to the Max
System.Globalization.Calendar namespace
The System.Globalization namespace offers additional
date and time related functionality through its Calendar
class. The Calendar represents and works on time in
divisions of days, weeks, months and years. Because
there are different kinds of calendars in use globally, the
Calendar class lets you work with several built-in types.
Correct date expressions based on local calendars
The .NET Framework has broad support for many local
calendars besides the standard western calendar that is
implemented in the GregorianCalendar class:
 JulianCalendar
 HebrewCalendar
 JapaneseCalendar
 KoreanCalendar
 ThaiBuddhistCalendar
 HijriCalendar
Two-way 2/4 digit-year windowed conversion.
The Calendar class contains a plethora of useful methods
for working with time and dates from a “calendar centric
view”:


AddDays: Returns the DateTime object resulting from
adding a fractional number of days to the specified
DateTime.
AddHours: Returns the DateTime resulting from
adding a fractional number of hours to the specified
DateTime.
.NET Framework Library











23
AddMilliseconds: Returns the DateTime resulting from
adding the specified number of milliseconds to the
specified DateTime.
AddMinutes: Returns the DateTime resulting from
adding a fractional number of minutes to the specified
DateTime.
AddMonths: Returns the DateTime resulting from
adding the specified number of months to the specified
DateTime.
AddSeconds: Returns the DateTime resulting from
adding a number of seconds to the specified
DateTime.
AddWeeks: Returns the DateTime resulting from
adding a number of weeks to the specified DateTime.
AddYears: Returns the DateTime resulting from adding
the specified number of years to the specified
DateTime.
Equals: (inherited from Object) Determines whether
the specified Object is the same instance as the
current Object.
GetDayOfMonth: Returns the day-of-month part of the
specified DateTime.
GetDayOfWeek: Returns the day-of-week part of the
specified DateTime.
GetDayOfYear: Returns the day-of-year part of the
specified DateTime.
GetDaysInMonth: Overloaded. Returns the number of
days in the specified month.
24
.NET Framework Library
Section 2: The System Namespace
The Console
System.Console class for console I/O
Although most applications today utilize a graphical user
interface, text based applications are still developed and
the ability to debug or quality assure (QA) applications
during development using a console window is invaluable.
To this end, the Framework offers a class specifically
encompassing “all things console”: System.Console.
Supports standard in, standard out, standard error
The Console class supports the standard in, out and error
that C/C++ users know so well.
Writing to the console
Writing to the console (or System.Console) is
accomplished using either the Write() or WriteLine()
method.
Console.WriteLine( “Hello World” );
Console also supports String.Format syntax:
Console.Write(
"Snowwhite and the {0} dwarfs",
7);
Reading from the console
Reading from the Console is as easy as writing:


Read(): Reads on characters
ReadLine(): Reads the input until a carriage return or
line-feed.
.NET Framework Library
25
Section 2: The System Namespace
Other System Goodies
The .NET Framework is choc-full-of “goodies” easing your
life as a developer and, best of all, you do not need to dig
for these helper namespaces and classes. The following
lists a few classes that exemplify this statement:
System.URI class
The URI class provides two-way parsing and construction
of URIs.
System.Random class
The Random class is a random number generator.
System.Radix class
Radix class enables numeric base-system conversions
(eg. Dec/Hex).
System.Convert class
Convert class is a one-stop place for core type
conversions.
26
.NET Framework Library
Section 3: Collection Classes
Section 3: Collection Classes
Section 3 introduces the collection classes. We start with
an overview over the Array. Then we will examine the
System.Collections namespace and have a look at the
different kinds of collection interfaces and classes.
.NET Framework Library
27
Section 3: Collection Classes
The Array
Only collection outside Collections namespace
System.Array is a special collection class, because it is
the only one outside the Collections namespace. It’s
subordinated to the System namespace, represents the
base class for all array types in the CLR, and provides
properties and methods to manage arrays.
This means that System.Array itself cannot be
instantiated. If you want to create an instance of a
managed array you have to specify the type of the array,
which at least consists of the element type, the rank, and
the lower bound(s). Depending on the given type an array
is mapped to language-intrinsic arrays.
Polymorphic, stores System.Object elements
Since everything in .NET is an object and derives directly
or indirectly from System.Object, System.Array stores
System.Object elements. The elements of an array
instance can be of any type, but all elements must be of
the same type.
You specify the element type at
declaration time.
Arbitrary number of dimensions, lengths
The dimensions of the array are specified at creation time;
in the moment you create the instance of the array
(CreateInstance). It can have any arbitrary number of
dimensions, which is referred to as the rank of the array.
But once the array is constructed, the dimensions are
fixed and cannot be changed. You even cannot add or
delete elements.
28
.NET Framework Library
The lower bound is the starting index of a dimension of an
array. A multidimensional array can have different lower
bounds for each dimension.
Supports sorting
System.Array has a public method Sort() which can be
used to sort the elements of a one-dimensional array
object. This method is overloaded and has a number of
implementations.
Sort() uses the interface IComparable that is implemented
by the elements of the array (internal comparison). If you
want to create your own logic for comparing elements, you
can implement the IComparer interface (external
comparison) and use another overloaded version of
Sort().
Supports binary searches on sorted arrays
Another thing to mention is that the Array class supports
binary searches on a sorted one-dimensional array. The
(overloaded) method is BinarySearch() and you can
search, for example, through the whole array or through
sections of it. Again you can use either the IComparable
interface for internal or the IComparer interface for
external comparison.
.NET Framework Library
29
Section 3: Collection Classes
Collection Interfaces (1/2)
A collection class can implement one or more methods of
one or more of the following interfaces.
IEnumerable
If you, for example, want to implement your own collection
class and want to use it with the foreach statement, you
must implement the IEnumerable interface.
IEnumerable has only one method GetEnumerator() that
returns an IEnumerator iterator.
IEnumerator is the base interface for all enumerators. It
supports one property Current to get the current element
of the collection and two methods MoveNext() and
Reset() to walk through the enumeration and set the
enumerator to its initial position. Enumerators cannot be
used to modify the underlying collection.
ICollection (inherits IEnumerable)
The ICollection interface is the basic collection interface
and inherits from IEnumerable. It defines a set of methods
common to all collections.
The most important ones are


Count(): takes the number of elements of the
collection.
CopyTo(): used to copy the ICollection elements to an
one-dimensional array.
30
.NET Framework Library
Section 3: Collection Classes
Collection Interfaces (2/2)
IDictionary (inherits ICollection)
The IDictionary interface is a basic association container
interface.
It’s an implementation of a collection of
key/value pairs.
Methods of interest are Add() and Remove() to add and
remove an entry to/from the IDictionary with the specified
key, Contains() lets you check whether the IDictionary
contains an entry with a certain key, and Clear() to
remove all entries from the IDictionary.
IList (inherits ICollection)
The IList interface inherits from ICollection and
IEnumerable. It is a basic list container interface – a base
class for all lists.
Methods of interest are the same as the ones explained
for the IDictionary interface: Add() and Remove() to add
and remove items to/from the list, Contains() lets you
check whether the list contains a certain value, and
Clear() to remove all items from the list.
.NET Framework Library
31
Section 3: Collection Classes
Collection Classes (1/3)
System.Collections.ArrayList / ObjectList
The
classes
System.Collections.ArrayList
System.Collections.ObjectList
are
dynamic
implementing the IList interface.
and
arrays
Unlike the System.Array class they can grow and shrink in
size, which means you can dynamically add or remove
elements from a list.
System.Collections.BitArray
System.Collections.BitArray represents a super-compact
array of bits. Each bit value is expressed as a Boolean.
So, if a single bit is turned on/off (1/0) its value is
“true/false”.
System.Collections.HashTable
The class System.Collections.HashTable is a fast hashtable implementing the IDictionary interface. It represents
a collection of key/value pairs that are organized in a hash
table using the hash value of the key.
Because there is no Dictionary class implementing the
IDictionary interface use the HashTable class if you want
to work with key/value pair collections.
System.Collections.SortedList
Another implementation of the IDictionary interface is the
System.Collections.SortedList class. This class organizes
the key/value pair collection using the key (and not a hash
value).
32
.NET Framework Library
Entries in this collection can be accessed using either
keys or indexes, but because of the sorting the access is
slower compared to a HashTable.
.NET Framework Library
33
Section 3: Collection Classes
Collection Classes (2/3)
System.Collections.Stack
System.Collections.Stack is a simple queue of objects. It’s
a stack implementation providing the methods Push() and
Pop() to insert and remove objects at the top of the stack.
It also provides the GetEnumerator() method to retrieve
an (IEnumerable) iterator of the stack.
System.Collections.Queue
A little different from the Stack class the
System.Collections.Queue class implements a first-in,
first-out collection. The methods to add and remove
objects are Dequeue() and Enqueue(). Dequeue()
removes an object at the bow of the queue, while
Enqueue() adds an object to the stern.
Like all other collection classes System.Collection.Queue
is fully enumerable.
34
.NET Framework Library
Section 3: Collection Classes
Collection Classes (3/3)
System.Collections.NameObjectCollectionBase
System.Collections.NameObjectsCollectionBase is an
abstract class that is the base class for sorted key/value
pair collections.
The key is of type System.String and the value is of type
System.Object. The entries can be accessed using either
the hash value of the key (so, this is a hash table) or
indexes.
Unlike the HashTable class this class allows duplicate
keys and keys that are null references.
System.Collections.NameValueCollection
System.Collection.NameValueCollection
is
an
implementation of the NameObjectCollectionBase class.
It supports a comma separated string list as the value for
a single key entry. For example, the HttpRequest.Headers
collection is a NameValueCollection of headers.
.NET Framework Library
35
Section 4: I/O and Networking
Section 4: I/O and Networking
This section covers the classes for file and network I/O.
Directories and Files
Streams, Stream Readers and Stream Writers
Isolated Storage
Networking Support
36
.NET Framework Library
Section 4: I/O and Networking
Directories and Files
Fully object-oriented way to explore the file system
The “objectiveness” of the .NET Framework Library shows
itself when you begin exploring the namespaces and
classes that are used to work with directories and files.
As a matter of fact, you are able to explore the file system
in a fully object-oriented manner!
System.IO.Directory represents a directory
In the System.IO namespace contains all you will need to
perform synchronous and asynchronous input and output
(IO), be it using a stream or file. When working with
directories and file, you will use the System.IO.Directory
and System.IO.File classes for directories and files
respectively. The Directory class methods to ease your
directory navigation and complement the File class.
Some of the methods include:



GetDirectories([mask]): Returns an array of Directory
objects containing the subdirectories that match the
specified mask.
GetFiles(…) Returns an array of File objects in the
current directory that match a specified mask or string
(file name).
CreateSubdirectory( [directory_name] ): Creates a
subdirectory to the current directory.
System.IO.File represents a file
Like the Directory class does for directories, the File class
provides a clean, object-oriented way to work with files.
Using the File class you can construct a file directly by
providing a file name or fully qualified path (i.e. path plus
.NET Framework Library
37
file name). Actually, if you supply only a file name,
internally the fully qualified path is used, based on the
current directory.
Another way to obtain a file object is of course to use one
returned from the GetFiles() enumeration of the Directory
object. The main difference to pretty much all other file
system APIs is that file directory entries and file objects
are really mapped into a single class.
Furthermore, the file system entries and stream access
are unified. For instance, all the Open...() methods - i.e.
Open(), OpenRead(), OpenWrite(), OpenText() - return
System.IO.Stream.
38
.NET Framework Library
Section 4: I/O and Networking
Streams
Abstract base-stream System.IO.Stream
System.IO.Stream is an abstract class for reading and
writing streams. Synchronous access is provided using
the Read() & Write() methods, while full asynchronous
support is achieved calling BeginRead() or BeginWrite()
and passing a callback. The specified callback is invoked
as soon as data is received.
To complete an
asynchronous call you should use the respective
EndRead() or EndWrite() method.
System.IO.FileStream
If you wish to open and access files directly, you can use
the FileStream object, which is the the actual
The actual object type returned by File.Open() is a
FileStream.
System.IO.MemoryStream
If you need to construct in-memory streams, you should
use the MemoryStream class.
.NET Framework Library
39
Section 4: I/O and Networking
Stream Readers (1/2)
Higher-Level access to Stream reading functions
The stream readers provide a higher-level means of
reading from streams.
System.IO.BinaryReader
The BinaryReader is designed for typed access to stream
contents and has the read methods for most of the core
data types: ReadInt16(); ReadBoolean(); ReadDouble();
etc.
System.IO.TextReader
TextReader is an abstract base class for reading strings
from streams. It is the base class for the StreamReader
and StringReader classes. Some of the methods include:





Peek(): Peeks into the stream and returns the next
character that will be read – but technically without
actually reading the character (i.e. the reading position
in the stream is not advanced).
Read(): Reads the next character or characters
(depending on the version used) from the stream.
ReadBlock(): Reads characters from the stream to a
character (array) buffer.
ReadLine(): Reads one line form the input stream (i.e.
it reads up until a carriage return or line-feed).
ReadToEnd() Reads from the current position in the
stream to the end and returns the result as one string.
40
.NET Framework Library
Section 4: I/O and Networking
Stream Readers (2/2)
The StreamReader and StringReader classes implement
the methods of their abstract base class, TextReader.
System.IO.StreamReader (implements TextReader)
The StreamReader is used to read characters from a byte
stream in a particular encoding. The default encoding is
UTF-8.
System.IO.StringReader (implements TextReader)
StringReader simulates stream input from a string. Like
StreamReader, it implements the methods of its base
class TextReader.
.NET Framework Library
41
Section 4: I/O and Networking
Stream Writers
High-level access to Stream writing functions
Complementing the read classes are corresponding write
classes: BinaryWriter, TextWriter, StreamWriter and String
Writer.
Designed and implemented in a consistent
manner as the readers, you will find them easily
understood and straightforward to use.
System.IO.BinaryWriter
Designed to write types in binary form to a stream.
Because there are over 15 strongly typed overloads for
the Write() method they are not listed here, but some of
the types handled include: bytes, signed bytes, long
integers, booleans, and unisigned integers.
System.IO.TextWriter
Like its counterpart the TextReader, TextWriter is an
abstract base class for writing strings to streams. In
addition to specifying countless overloaded Write()
mehthods, it contains corresponding WriteLine() methods.
It is worth noting that some of these methods include
placeholder-formatted strings.
System.IO.StreamWriter (implements TextWriter)
Supports writing strings to streams using a user specified
encoding, such as the default UTF-8.
System.IO.StringWriter
Simulates stream-writes on an output string.
42
.NET Framework Library
Section 4: I/O and Networking
Isolated Storage
Isolated storage is a new concept of the .NET Framework
library that allows applications to allocate private storage
area without worrying about the system’s file system
layout. More precisely, Isolated Storage provides an
isolated file system within the actual file-system that
somewhat resembles the structured storage facility of
COM in that it is implemented on a file whose location is
managed by the common languages runtime.
This enables .NET applications and downloaded .NET
controls to persist data on disk although they may not
have permissions to access the “regular” file system.
Isolated Storage uses a different set of permissions. The
storage area is fully isolated (or “sandboxed”) from the
rest of the system and is subject to disk quotas so that
each control or downloaded application may only use a
certain amount of disk storage.
Scoped, isolated virtual file system
Isolated Storage can be scoped to a single user, which
allows parallel isolated storage areas on a per-user basis
for the same application or control. Isolated storage can
also be scoped to the assembly, which means that all
users share the same isolated storage area and the
isolated storage is accessible only for a certain assembly.
If you choose application domain scope, you can use
isolated storage scoped to each logical .NET process
(AppDomain), even if multiple application domains
execute concurrently based on the same Assembly.
Isolated storage is great for any type of temporary and
short-lived persistent data, which is scoped to a certain
application. There are no file-name clashes with other
.NET Framework Library
43
applications to look out for and applications don’t need to
worry about the location and/or access rights for the
“TEMP” directory on the local drive.
As stated before, Isolated storage is entirely sandboxed,
so that applications using isolated storage can use the
local hard drive in a very controlled manner without
compromising overall system security.
Storage location managed by runtime system
The storage locations for Isolated storage and the quotas
are automatically managed by the runtime system. Global
settings for the isolated storage subsystem can be
configured using the standard .NET configuration
mechanisms using enterprise-level, machine-level or
application-level configuration files.
System.IO.IsolatedStorage.IsolatedStorageFile
The IsolatedStorageFile class is the container for
IsolatedStorageFileStreams and represents a virtual file
system. You can create a new storage file (or access an
existing one) through the static class methods GetStore,
GetUserStoreForAssembly and
GetUserStoreForDomain.
The IsolatedStorageFile lets you manage files (file
streams to be precise) and an entire directory structure.
[...] IsolatedStorageFileStream
The IsolatedStorageFileStream represents a file within an
isolated storage directory and behaves exactly like the file
streams that you work with using the regular file system
classes.
44
.NET Framework Library
Section 4: I/O and Networking
The Net in .NET: System.Net
.NET wouldn’t deserve the name .NET without
comprehensive support for networking. Underneath the
high-level technologies like WebServices or ASP.NET act
the networking classes that are contained in the
System.Net namespace.
System.Net contains all network protocol support
The namespace System.Net contains the complete
support for all network protocol options in the .NET
Framework. This covers both, low-level network access
through sockets and application-level protocols like HTTP.
Low-level support for IP sockets and IPX
The socket library in System.Net.Sockets supports various
protocols that run on top of the Internet Protocol (IP) and
has explicit helper classes for TCP and UDP. The Novell
network protocol IPX is also supported.
Application level protocol implementations (HTTP)
The support for application level protocols and access to
essential parts of the networking infrastructure (such as
the Domain Name Services, DNS) resides directly in the
System.Net namespace.
The System.Net namespace also contains a complete
client and server (!) infrastructure for HTTP and allows
plugging in your own protocol handlers.
Authentication methods for HTTP
For HTTP, System.NET has full support for Basic and
Digest authentications compliant to RFC2617 and also
supports the Windows NTLM authentication scheme.
.NET Framework Library
45
Full cookie support for HTTP
The HTTP client and HTTP server implementation also
has full support for sending and evaluating HTTP cookies.
46
.NET Framework Library
Section 4: I/O and Networking
Request and Response Classes
System.Net.WebRequest class
The core of the application-level protocol support through
which you can access HTTP and which also allows you to
create and plug-in your own protocols, is made available
through the WebRequest class.
The WebRequest class is an abstract base class, which
provides
a
basic
infrastructure
for
creating
Request/Response interactions based on any applicationlevel protocol. The .NET Framework supplies a standard
implementation for HTTP and HTTPS through the
HttpWebRequest class.
Create requests through WebRequest.Create()
Web requests are created through the Create() method on
the WebRequest class, providing an HTTP URL.
Plug in new protocol handlers with RegisterPrefix()
The HttpWebRequest implementation is automatically
registered with the WebRequest infrastructure using the
protocol prefixes “http” and “https”. If you want to use your
own protocol implementations with the WebRequest
infrastructure, you can hook in your protocol handlers by
registering a custom protocol prefix together with an
implementation of the IWebRequestCreate interface.
Request can be populated through stream
Each implementation of a web request class returns a
stream (System.IO.Stream) that allows you to provide the
data to be sent in the request. You can obtain the stream
reference by calling WebRequest.GetRequestStream().
.NET Framework Library
47
Request is executed on GetResponse()
With the HTTP protocol family, the request is sent once
you
request
the
result
by
calling
the
WebResponse.GetResponseStream()
method.
The
response stream (also an instance of System.IO.Stream)
contains the entire result as received from the server side.
48
.NET Framework Library
Section 4: I/O and Networking
Protocol Support Classes
Manage connectivity through ServicePoint
To limit the number of outbound sockets to be established
and make use of advanced HTTP features like persistent
connections to optimize client/server interaction, .NET
manages connections through
the ServicePoint
infrastructure. For web requests, all endpoints are
managed by the ServicePointManager and ServicePoint
classes and enable that multiple web requests that target
the same endpoint will reuse or share an existing endpoint
connection if present, instead of reopening a new socket
for each request.
The ServicePoint class will also let you query SSL
certificate information and lets you control various
connection parameters that are common to all
connections to a particular host.
Shared service points allow for an overall greater
scalability of your application, because they efficiently
manage the limited number of sockets that are available
for the entire system.
System.Net.EndPoint information in ServicePoint
The end points (connection targets) of service points are
implemented on top of the protocol agnostic EndPoint
class, which has specialization for the Internet Protocol
(IP) in System.Net.IPEndPoint and for Novell IPX in
System.Net.IpxEndPoint.
System.Net.DNS
The System.Net.DNS class provides access to DNS
name-servers and gives easy access to name resolution
through the GetHostByName() and Resolve() methods.
.NET Framework Library
49
The DNS class uses the DNS server information
configured in the system’s default IP protocol stack.
50
.NET Framework Library
Section 4: I/O and Networking
IP Sockets
The
socket
library
that
is
implemented
in
System.Net.Sockets is the reincarnation of the Berkeley
sockets library on the .NET platform. Berkeley sockets
had been adopted for Windows with the WinSock API and
now found its way into the .NET Framework in a
modernized and object-oriented, but still very familiar
form.
System.Net.Sockets.Socket for raw sockets
The Socket class within the System.Net.Sockets
namespace groups all socket related functions in a single
class. To create a new socket, you simple create an
instance of the socket class, connect the socket with
Connect() and can then use the familiar Send() and
Receive() methods to send or read data from the socket.
Socket.Connect() connects to EndPoint
The Connect() function connects to an EndPoint
representing a TCP, UDP, IP multicast, IPX or other
protocol binding.
Socket.Bind() and Socket.Listen() create listener
If you need to implement a server, you can Bind() the
socket to a specific endpoint and enter listening on that
endpoint using the Listen() method, just as you would do it
with the plain WinSock API or Berkeley sockets on Unix.
High-Level wrappers for TCP, UDP
In addition to the low-level socket APIs that are available
on the Socket class, .NET adds higher-level wrappers for
plain sockets that make low-level network connections
truly easy to use:
.NET Framework Library
51
The TcpClient and UdpClient classes wrap the socket
functionality and provide access to a NetworkStream class
instance that acts exactly like a local file stream and lets
you use the StreamReader and StreamWriter
infrastructure on a networking socket.
The TcpListener class is a higher-level implementation for
a TCP server process that wraps the socket class.
TcpListeners are started with Start() and stop listening
with Stop(). The method Accept() will block until a client is
connected and will then return a socket that you can use
to communicate with the client. That socket can then be
passed to a new NetworkStream object, which can be
served on a different thread.
52
.NET Framework Library
Section 5: Process Management
Section 5: Process Management
Process control
A Process component provides access to an executable
running on a computer. A process, in the simplest terms,
is a running application.
Threading support
A thread is the basic unit to which the operating system
allocates processor time. A thread can execute any part of
the process code, including parts currently being executed
by another thread.
The framework provides a set of classes to create and
monitor threads as well as synchronizing mechanisms.
.NET Framework Library
53
Section 5: Process Management
Processes
System.Diagnostics.Process class
This class provides access to
processes can be local or remote.
processes.
These
Allows creating/monitoring other processes
The Process class is a useful tool to monitor applications.
Using the Process class, you can obtain a list of
processes that are running, or start a new process.
A Process class is used to access system processes.
Once a Process class has been initialized, it can then be
used to obtain information about the running process,
such as the set of threads, loaded modules (.dll or .exe's),
or performance information such as the amount of
memory the process is using, in addition to all information
that is presented through the Task Manager. Once the
Process class has obtained information about the
associated process, it will not try to obtain it again until
you call the Refresh method.
A system process is identified uniquely on the system by
its process ID. In addition, a process, like many Windows
resources, has a handle by which it identifies itself, but
which may not be unique on the computer. A handle is the
generic term for an identifier to a resource. The process
handle, accessed through the Handle property on the
Process class, is persisted by the operating system even
when the process has exited so that you can get
administrative information about the process, like the
ExitCode (usually, 0 for success or a non-zero error
code) and the ExitTime.
54
.NET Framework Library
Handles are an extremely precious resource, so leaking
handles is more virulent than leaking memory. The
operating system will only release the handle and
associated data when there are no longer any handles to
the process on the system, when the HandleCount is 0.
Process.Start() equivalent to Win32 ShellExecute
The Process class implements four ways to start a
process.
The first is an instance method, that simply starts the
process that is described by the StartInfo property of that
instance. The procedure is creating an instance of
Process, setting the StartInfo data accordingly and then
calling Start() on that Process instance.
The other three ways are static methods of the Process
class, that take different parameters:

A ProcessStartInfo object,

a string specifying the name of a document or
application file or

two strings specifying the name of an application and a
set of command line arguments.
The StartInfo property or parameter also serves for
specifying a command verb like “print” or “open”. This
action is immediately executed after the process has
started and documents are loaded.
Supports waiting for termination (WaitForExit)
Calling WaitForExit without any parameter suspends
execution of the current thread and waits for termination of
the monitored process. A registered event handlers for the
Exited event is called upon termination of the process.
It is possible to wait for termination only for a specified
time interval. The WaitForExit method with an interval as
parameter returns true, if the process actually terminates,
and returns false, if that interval elapses without
termination of the process.
Explicit termination supported in two ways
Whenever you use Start to start a process, you must be
sure to close it or you risk losing system resources. You
close processes in a more cooperative way using
CloseMainWindow or with a final and uncompromising
way using Kill. CloseMainWindow is used to close
processes that contain a graphical interface, while Kill
must be used for non-graphical applications that do not
have a message pump to handle a windows Close
request.
Calling CloseMainWindow revokes all running message
loops on all threads and closes all windows. The request
.NET Framework Library
55
to exit the process by calling CloseMainWindow does not
force the application to quit. It can ask for user verification
to perform the shutdown, or it can refuse shutdown if the
application is running a macro. To force a shutdown, use
Kill. The behavior of CloseMainWindow is identical to
that of a user closing an application's main window using
the system menu. Hence, the request to exit the process
by closing the main window does not force the application
to quit immediately.
Note Currently, all processes started using a Process
class open in a command window. They contain a
message loop and you can attempt to close them using
CloseMainWindow. This will change in a future release.
Depending on how the non-graphical interface process is
coded, CloseMainWindow could fail and Kill could be
necessary in order to stop the process.
56
.NET Framework Library
Section 5: Process Management
System.Threading.Thread
Every .NET application is fully multi-threaded
One or more threads run in an AppDomain. An
AppDomain is a runtime representation of a logical
process within a physical process. A thread is the basic
unit to which the operating system allocates processor
time. Each AppDomain is started with a single thread, but
can create additional threads from any of its threads.
In contrast to programming under COM there are no more
threading models like single or multi apartment threading.
When using COM Interop however, developers need to be
aware of the threading characteristics of the COM classes
they’re using in order to write the most efficient code.
There is definitely a trade-off for this simple and efficient
model: the programmer is responsible for synchronization:
no automatic access synchronization is accomplished by
the runtime.
System.Thread represents a system thread
Creating a new instance of a System.Threading.Thread
object can create new managed threads. The constructor
for System.Threading.Thread takes, as its only parameter,
a Thread Delegate.
The delegate references a method in some class, that
serves as the entry point of the thread. This method itself
cannot be declared having any parameters. The thread’s
launch-state is set on the object hosting the delegate’s
method.
.NET Framework Library
57
ThreadPool implicitly created for each process
There are many applications that create threads that
spend a great deal of time in the sleeping state waiting for
an event to occur. Other threads may enter a sleeping
state only to be awakened periodically to poll for a change
or update status information.
Thread pooling enables you to use threads more
efficiently by providing your application with a pool of
worker threads that are managed by the system. One
thread monitors the status of all wait operations queued to
the thread pool. When a wait operation has completed, a
worker thread from the thread pool executes the
corresponding callback function.
The thread pool for the process is created the first time
you call ThreadPool.QueueUserWorkItem, or when a
timer or registered wait operation queues a callback
function.
58
.NET Framework Library
Section 5: Process Management
Creating Threads
This sample shows how a thread is created, started and
how the original and the newly create thread are
synchronized again.
The class Pulsar implements the thread’s entry point
method Run(). An object of this class must be created
first.
Pulsar pulsar = new Pulsar();
A new TreadStart object is created using the Pulsar.Run()
method as entry point.
ThreadStart threadStart =
new ThreadStart(pulsar.Run);
The actual thread object is created with the ThreadStart
as parameter and started right away.
Thread thread =
new Thread(threadStart);
thread.Start();
While the newly created thread is executing, the original
thread can perform any other task, especially create some
other threads.
When the original thread is done with it’s work and wants
to synchronize again with the new thread, it just executes
the Join() method on that new thread and execution is
halted until the new thread terminates, that is the entry
point method returns.
thread.Join();
.NET Framework Library
59
Section 5: Process Management
Thread Synchronization Monitor
System.Threading.Monitor class
The System.Threading.Monitor class provides the means
for synchronization of threads, that are very similar to the
Win32 critical sections method. It is used to form a
synchronized block in a way, that only a single thread can
modify a certain object. Monitors are used within the code
of the threads that are to be synchronized.
The two static methods Enter and Exit are used to form
the entry and exit of the block. The object to be accessed
in a synchronized matter is given as a parameter. In our
sample, it is the object implementing the thread’s method
itself, but it can be any instantiated managed object. Only
one thread can be active in this block, i.e. modify the
member internalState (in that sample) at a time.
C# has a special keyword lock that is mapped internally
to a Monitor Enter/Exit block.
The Monitor class supports a Wait/Pulse coordination
model. This allows for more advanced control of
execution. Within a synchronized block a thread can call
the static method Wait() to pause execution at that point.
The executing thread is put into a waiting queue. If
another thread is waiting at the block’s entry or just
arriving it is allowed to enter the block.
Threads in the waiting queue are halted until another
thread executes the Pulse method. Then the next thread
in the waiting queue is moved to the ready queue. As
soon as the thread that invoked Pulse releases the lock,
the next thread (if there is one) in the ready queue is
allowed to take control of the lock.
60
.NET Framework Library
Section 5: Process Management
More Threading
Synchronization with WaitHandle
The WaitHandle class represents all synchronization
objects in the runtime that allow multiple wait. This object
is a singleton that is created by the runtime. It
encapsulates Win32 synchronization handles and is
subclassed for threads, mutexes, events etc.
Mutexes are in contrast to synchronization blocks single
points of synchronization. WaitOne, WaitAll and WaitAny
can be used to request ownership of the mutex or a group
of mutexes respectively. The state of the mutex is
signaled if no thread owns it.
The thread that owns a mutex can specify the same
mutex in repeated wait function calls without blocking its
execution. It must release the mutex via ReleaseMutex
as many times to release ownership.
A ManualResetEvent object represents an event object
whose state can be manually set and reset. The state of a
manual-reset event object remains signaled until it is set
explicitly to the nonsignaled state by the Reset method.
Any number of waiting threads, or threads that
subsequently begin wait operations for the specified event
object by calling one of the wait functions, can be released
while the object's state is signaled.
AutoResetEvent remains signaled until a single waiting
thread is released, at which time the system automatically
sets the state to nonsignaled. If no threads are waiting,
the event object's state remains signaled.
.NET Framework Library
61
Threading Timers for timed callbacks
The System.Threading.Timer class is used to set up a
callback via a delegate that is invoked on it’s own thread
after a specified time interval has elapsed.
The timer is set to the signaled state when its specified
due time arrives. Any thread with a handle to the timer can
use one of the wait functions to wait for the timer state to
be set to signaled.
Interlocked class for lightweight locking
The Interlocked class provides the mechanism for
synchronizing access to an integer variable that is shared
by multiple threads. The threads of different processes
can use this mechanism if the variable is in shared
memory. The Increment and Decrement methods
combine the operations of incrementing or decrementing
the variable and checking the resulting value. This atomic
operation is useful in a multitasking operating system, in
which the system can interrupt one thread's execution to
grant a slice of processor time to another thread. Without
such synchronization, one thread could increment a
variable but be interrupted by the system before it can
check the resulting value of the variable. A second thread
could then increment the same variable. When the first
thread receives its next time slice, it will check the value of
the variable, which has now been incremented not once
but twice. The interlocked variable-access functions
protect against this kind of error.
The Exchange method atomically exchanges the values
of the specified variables. The CompareExchange
method combines two operations: comparing two values
and storing a third value in one of the variables, based on
the outcome of the comparison.
62
.NET Framework Library
Section 6: Advanced Services
Section 6: Advanced Services
In the final section of this overview on the .NET
Framework library we look at some of the advanced
services available in the Library. This section covers the
classes and namespaces that provide access to Windows
2000 services like Active Directory or Windows
Management Instrumentation and how your .NET
applications can report errors, warnings or status
information via the Windows event logging facility.
Windows 2000 Services
Diagnostics and Profiling
.NET Framework Library
63
Section 6: Advanced Services
Windows 2000 Services
System.Management
The System.Management namespace provides access to
the Windows Management Instrumentation (WMI) system
in Windows 2000. The WMI implementation in the .NET
Framework provides a completely object-oriented view on
WMI classes and is much more elegant and much more
intuitive than the original WMI API.
You
can
access
WMI
objects
using
the
ManagementObject class and can manage WMI classes
using the ManagementClass class. If you need to query
for objects you can easily run WQL queries using the
ManagementObjectSearcher class.
System.Messaging
The System.Messaging namespace provides access to
the Microsoft Message Queue services. In addition to the
MessageQueue class that you would expect to be in a
message queue centric namespace, System.Messaging
provides a complete message formatter infrastructure that
allows you to create and parse queued messages in
binary format (.NET native formats), XML and a
specialized “ActiveX” formatter that is compatible with the
COM data-types and stream formats so that .NET
applications and COM applications can seamlessly
exchange information through MSMQ.
In addition, the namespace provides filtering and
enumeration facilities which allow you to pick only those
messages from the queue that satisfy a certain set of
criteria. Using this you can share a message queue
among several specialized worker threads.
64
.NET Framework Library
System.DirectoryServices
The DirectoryServices namespace is the .NET
Framework’s gateway to access the Active Directory
infrastructure.
The DirectoryEntry class gives you here very easy access
to directory entries (and schema entries) and the
DirectorySearcher lets you search the directory.
The properties of a DirectoryEntry are available on the
Properties collection and due to the common type system
automatically provided in the correct, native data type.
System.ServiceProcess
If you want to run .NET managed applications as
Windows NT or Windows 2000 service processes, you
don’t need to look any further than the ServiceBase baseclass located in the Windows ServiceProcess namespace.
ServiceBase provides all of the essential plumbing and
entry points to your .NET based process and all you need
to do is to override the “OnStart” method to start up your
service process and the “OnStop” method to shut down all
listeners and worker threads gracefully.
To deploy your services process you can use the
“InstallUtil.exe” utility provided with the .NET Framework.
This utility will trigger the ServiceInstaller class that
registers your services with the system. ServiceBase
provides a default implementation, but you can also
provide a customized ServiceInstaller for a more
specialized installation, including running services on
specific user accounts or installing services that are
manually started or initially disabled. The default installer
will install the service to start automatically under the local
system account.
.NET Framework Library
65
Section 6: Advanced Services
Windows 2000 Event Log
System.Diagnostics.EventLog class
The EventLog class in the System.Diagnostics
namespace provides access to the Windows NT and
Windows 2000 event log and lets you both read from and
write to the event log.
Reading event logs
The static method EventLog.GetEventLogs() lets you
query all logs on a specific machine and returns them as
an array of EventLog objects. Each instance of EventLog
represents a single log, such as the Application, Security
or System log. The EventLog.Log property indicates the
type of the event log.
The EventLog.Entries property retrieves all entries for a
log returning an EventLog.EventLogEntryCollection object
that contains EventLogEntry elements.
Instead of polling for event log entries you can also install
an event handler with the EventLog class that will be
triggered each time a new entry is added to the log.
Writing event logs
Just as with the unmanaged event log APIs, writing to the
event log requires registering an event log source.
Registering event sources is done through the static
method CreateEventSource(). This method registers the
application and associates it with a certain event log.
All calls to WriteEntry() on the EventLog class with a
“Source” property matching the registered source string
will then be written to the specified log. Note that the
external message tables of the Win32 event log API are
not explicitly supported or wrapped by .NET.
66
.NET Framework Library
Section 6: Advanced Services
Other Diagnostic Services
In addition to the event log, .NET provides quite a few
more diagnostics services (including, of course, the
debugger interfaces). The most useful for your
applications might be the following:
System.Diagnostics.PerformanceCounter
The PerformanceCounter class will let you access existing
performance counters on the Windows NT and Windows
2000 platforms to query them and allows you to create,
register and update your own global performance
counters.
System.Diagnostics.StackTrace
Whenever your application gets caught in an unexpected
situation from which you either cannot recover gracefully
and need to provide diagnostic information for support log
files or where you need current information about which
code has been calling your code for another reason, you
can create an instance of the StackTrace class, which will
create a stack trace reflecting the call stack of the present
location within your application.
The StackTrace is a collection of StackFrame instances
that each include the full name and signature of the calling
method as available through Reflection and the IL-based
“instruction pointer” from where the call was executed.
Each stack frame also contains a reference to the
implementing source code file and line, if debug
information is present in the metadata.
System.Diagnostics.Trace
The Trace class allows code instrumentation with
diagnostic output. You can use the Trace class to
.NET Framework Library
67
instrument your code with diagnostics and “health watch”
information that is available at runtime through registering
TraceListeners.
VisualStudio.NET automatically registers such handlers to
produce output for the “Output” window in the Debugger
and therefore has tracing enabled at all times.
Using a switch on the compilers you can entirely disable
any code-generation for calls to the Trace class for your
release versions, so that you can leave your code fully
instrumented at all times.
68
.NET Framework Library
Summary
Summary
Of course, this module could only provide a very highlevel overview on the wealth of the .NET class universe
and we couldn’t do much more than highlighting a number
of classes that you may want to look up in the .NET
Framework library documentation.
The .NET framework is huge and there is a lot to learn –
the pleasant aspect is that it is all in one place and nicely
organized into a hierarchy of namespaces instead of
cluttered all over the system with a plethora of different
API implementation technologies and implementation
styles.
Everything is based on System.Object
All classes are based on System.Object, whose methods
we covered and highlighted.
Rich set of foundation classes
The object-ness of all classes enables the .NET
Framework to provide rich, fully polymorphic collection
and utility classes that work with any type and provide
solutions for most of the common developments tasks.
Comprehensive set of general-purpose, object-oriented classes
for Networking and I/O
Networking and file-system access in .NET is now easier
than ever before. The .NET Framework provides a fully
object-oriented way to navigate and access file-system
objects and provides a flexible and extensible networking
infrastructure.
.NET Framework Library
69
Great access to Windows 2000 services
Windows 2000 and Windows NT services, which
contribute to the success of the Windows 2000 platform
are fully accessible from .NET through clean, objectoriented and redesigned programming interfaces.
Rich diagnostic and monitoring facilities
Just because server applications run invisibly, they don’t
need to run silently. With the built-in diagnostic and
monitoring facilities, you can provide information from
within your .NET applications for complete runtime
behavior transparency and enhanced maintainability.
Download