Building Distributed Applications
Monitoring in .NET Distributed Application Design
 

patterns and practices home

Related Links

patterns and practices Index

.NET Architecture Center

Application Architecture for .NET: Designing Applications and Services

Amitabh Srivastava and Edward Jezierski
Microsoft Corporation

August 2001

The patterns & practices team has decided to archive this content to allow us to streamline our latest content offerings on our main site and keep it focused on the newest, most relevant content. However, we will continue to make this content available because it is still of interest to some of our users.
We offer this content as-is, without warranty that it is still technically accurate as some of the material is undoubtedly outdated. Note that the content may contain URLs that were valid when originally published, but now link to sites or pages that no longer exist.

Summary: Windows Management Instrumentation (WMI) is the preferred monitoring technology on the Windows platform. This article provides an intro to WMI and discusses the monitoring process in the context of .NET applications. (51 printed pages)

Contents

Introduction
The Monitoring Process
An Introduction to WMI
Instrumenting .NET Applications
Monitoring and Supporting .NET Applications
Conclusion

Introduction

Application monitoring is used to ensure that applications are functioning correctly and are performing optimally. Within most companies, application monitoring is generally the responsibility of administrators and operators within the operations team. It is critical for an operations team to establish guidelines and procedures for application monitoring. Communicating these procedures to developers within the development team allows both teams to work together to log and monitor information that can greatly assist both problem discovery and problem diagnosis. This is an ongoing process that requires revision; both the operations and development teams should strive to continually refine monitoring processes.

Instrumentation metrics are equally valuable to both teams. Operators can use instrumentation data to perform capacity planning and health monitoring. Developers can use instrumentation data to design, build, and optimize high-performance applications.

Operators can also improve the quality of an application by judiciously recording problem history and details of their resolutions. By communicating this information to the development team, the developers can improve their future system designs and the diagnostic capabilities of their applications.

Error logging is closely related to monitoring and is primarily a development function. You should design an appropriate strategy for error management at an early stage during the design phase. For more information about designing and developing an application error management system utilizing .NET technologies, see Exception Management in .NET. It is important that the development team communicate with the operations team to inform them of the types of error logs generated by every application. In turn, the operations team must relay to the development team the various mechanisms that are available for monitoring errors. Together, both teams must decide on the appropriate logging mechanisms, and then develop and monitor applications accordingly.

In some situations, development may be decoupled from operations, and the developers cannot interact with the operators who monitor the application in the production environment. The use of a common object model technology allows discoverability of the manageable objects without the need for direct communication between the authors and consumers.

Windows Management Instrumentation (WMI) is the preferred monitoring technology on the Microsoft Windows® platform. Because WMI is native to the Windows platform (and therefore to the .NET Framework), many advanced monitoring techniques can be implemented by interacting with the WMI object model via classes contained within the Framework Class Library.

For more information about WMI, refer to the Windows Management Instrumentation on MSDN.

You should monitor your applications for two primary reasons. Firstly, monitor your applications to ensure that they are functioning correctly; this is referred to as health monitoring. Secondly, monitor the performance characteristics of your servers, because this may allow you to spot usage trends and enhance or optimize your applications accordingly.

Health Monitoring

Health monitoring enables you to identify the conditions that contribute to system failure and take preventive action.

You can already monitor events in the Microsoft® Windows NT® event log or other logging resources to spot fatal errors or warning conditions that can signal the start of a problem. You can use third-party tools to monitor events and performance data thresholds; for example, when the CPU on a particular computer exceeds 95 percent of its capacity. These tools raise events of particular significance to administrators for resolution. You can also elect to create your own diagnostic procedures and monitoring tools.

Performance Monitoring

Microsoft Windows® performance counters allow your applications and components to capture and analyze the performance data that applications, services, and drivers provide. You can use this information to determine system bottlenecks and fine-tune system and application performance.

For example, you might use a performance counter to track the amount of time required to process an order or to query a database, or you might monitor the size of a message queue and write code that performs a specific action whenever the queue reaches a preset limit. WMI also supports writing data back to the application. In this case, the action could be sending e-mail to someone. However, it can also provide an automatic corrective action, such as increasing the queue size to accommodate the load. This can also be done through WMI if the queue size is an instrumented piece of configuration data.

The Monitoring Process

Monitoring Process Flow

Figure 1 illustrates the process of application instrumentation and monitoring, and highlights the various technologies involved.

Ee957925.monitordotnet01(en-us,MSDN.10).gif

Figure 1. Monitoring process flow

The process and technologies can be subdivided into five key areas.

  • Analysis
    Developers and operators (A) need to collaborate and understand the behaviors and thresholds of the applications to be monitored to establish requirements. Working proactively with a defined set of requirements and a thorough analysis of the system, a strategy to monitor the application is reached. This often requires further refinement after initial prototyping and testing activities.
  • Application instrumentation
    Applications can then be instrumented (B) to expose performance counters or objects that publish events to notify interested subscribers of particular conditions and state changes occurring within the application.
  • Common services technology
    The technology that facilitates instrumentation and monitoring is WMI (C). WMI is based on industry standards and is used by many Microsoft applications. Application management suites such as Microsoft Operations Manager (MOM), Application Center Server (AC), and Systems Management Server (SMS) take advantage of common services such as WMI and are included as part of the operating system infrastructure. This means that an appropriate infrastructure service is always available to be leveraged into a management solution.
  • Development technology
    Custom code (D) can be built using numerous implementation technologies such as the WMI SDK (E), Managed code (F), and Microsoft Visual Studio® .NET (G), provides tools to help instrument and monitor applications.
  • Management
    Instrumented applications and monitoring systems are then deployed and managed (H). WMI Providers act as intermediaries between WMI and one or more managed objects, for example those added to the application during stage 2. Consumers receive the events and information supplied by the providers.

In .NET, developers are not required to write a provider to publish data or events. The technology in the .NET Framework allows developers to simply annotate their application classes to make them available for management—so there is no need for a full-fledged "provider."

An Introduction to WMI

Microsoft Windows Management Instrumentation (WMI) technology is an implementation of the Desktop Management Task Force's (DMTF) Web-Based Enterprise Management (WBEM) initiative and the DMTF Common Information Model (CIM).

WMI allows you to hide the complexities associated with the monitored environment. The CIM schema, which is also a DMTF standard, presents a consistent and unified view of the various types of logical and physical objects contained within the environment such as software components, services, and printers. Management objects are represented as classes. These classes include properties that describe data and methods that describe behavior.

WMI follows the publish-subscribe idiom. WMI providers, which abstract the underlying detail of the managed object, publish events. Meanwhile, WMI consumers subscribe to selected events and receive notifications when events are published. Providers can also provide on-demand data, single objects, or collections of single objects when a consumer requests them.

Technology Components

WMI technology consists of:

  • Management infrastructure
    This includes the CIM Object Manager (CIMOM) and the CIM Object Manager Repository, used primarily to store schema definitions and provider-binding information. Typically, the data is retrieved dynamically from the provider on-demand.
  • WMI consumers
    Consumer components and applications monitor for WMI events through the CIMOM and allow you to perform actions upon the receipt of an event.
  • WMI providers
    These act as intermediaries between the CIMOM and the underlying managed objects (including your applications and components). The providers interact with the WMI object model and supply the CIM Object Manager with data from managed objects, handle requests from management applications, and generate event notifications, indicating that an underlying state change has occurred within the managed object.

Figure 2 illustrates the basic WMI technology components and illustrates the relationship between WMI consumers and providers.

Ee957925.monitordotnet02(en-us,MSDN.10).gif

Figure 2. WMI technology components

Benefits

WMI helps you make your applications manageable, even in complex environments. You can identify and expose information that might be valuable for system or network administrators, helpdesk staff, or your product support organization. You can also monitor, configure, and control your product through off-the-shelf management tools or custom administrative tools and scripts. Using WMI, you can enable a wide range of tasks. For example, you can:

  • Monitor the operational state of your application.
  • Determine the health of your system components.
  • Measure internal and end-to-end performance, either by direct interrogation or through a notification mechanism that alerts you when something changes.
  • Configure application initialization settings such as timeout values, user count thresholds, and database connection strings.
  • Relate management data together to illustrate the relationships between objects.

Here is a simple example of a WMI Microsoft Visual Basic® version 6.0 script that lists the storage devices on your local computer:

Set services = GetObject("winmgmts://localhost")
Set myenum = services.ExecQuery("select * from Win32_LogicalDisk")
' Display each disk using a message box
For Each disk In myenum
  WScript.Echo (disk.DeviceID)
Next

You can use WMI to monitor entire computers and suites of computers, in addition to individual applications. This allows you to identify and expose information that might be valuable for system or network administrators, helpdesk staff, or your product support organization, which can then monitor, configure, or control your product through off-the-shelf management tools or custom administrative tools and scripts.

Some examples of management data well suited to being exposed through WMI include:

  • Component support information
    Including manufacturer names, version numbers, and updates applied.
  • Component status
    Indicating, for example, whether a component is processing, idle, or disabled.
  • Configuration information
    Including information you might usually store in the Windows registry, or runtime settings that can be changed dynamically.
  • Interesting events
    For example, error reporting, logon failures, significant status changes, NTEventLog entries, W2K Traces, VISTA events, SNMP MIB translation to events, and so on. Also, state change events on objects (intrinsic events) or customized app/service events (extrinsic events).
  • Performance information
    Including performance counters and other statistical data that can change rapidly.
  • Describing the relationships between objects
    For example, illustrating which files a database uses, which users have access to your service, or what network protocol stack your component is using.

You can also use WMI to configure various aspects of your application, such as:

  • Management operations
    For example, running a diagnostic function, resetting a component, or compressing a file.
  • Creating new objects
    For example, adding a new table to a database or creating a new user.
  • Modifying settings on existing objects
    For example, setting the permissions for a user on a share, changing the proxy server settings that your application uses, or modifying the initialization parameters of your service.
  • Deleting objects
    For example, removing a user account or deleting a file.

Architecture

Figure 3 illustrates the complete WMI architecture and includes examples of WMI consumers and providers. The top of the diagram shows examples of management applications (consumers), which might include browser-based Web applications, Microsoft Management Console (MMC) snap-ins, or custom Win32 applications.

Ee957925.monitordotnet03(en-us,MSDN.10).gif

Figure 3. Windows Management Instrumentation architecture

Internal WMI architecture consists of the CIM Object Manager (CIMOM) and the CIMOM Object Repository, as well as WMI providers for the Win32 environment. The CIM Object Manager handles the communication of information between data providers and data consumers such as the SMS Administrator console or a reporting application making calls to the WMI Scripting API. The CIMOM Object Repository holds the CIM schemas, which the Object Manager uses when it services requests that applications make for CIM objects.

Custom Win32 applications typically access COM interfaces directly to interact with the CIM Object Manager to make management requests, while others use additional access methods such as Open Database Connectivity (ODBC), ADSI (Active Directory Service Interface) interfaces, or the Windows Management Instrumentation scripting API (previously called WBEM Scripting) to make their requests.

The lower part of the diagram illustrates examples of managed objects and associated providers; for example, the Windows Registry and the associated Registry Provider. Communication between CIM Object Managers on local and remote computers uses the Distributed Component Object Model (DCOM). For more information, see WMI Architecture in the Windows DDK.

Providers and adapters

The WMI SDK also includes built-in object providers and application adapters. Management applications can use the built-in object providers to access data and event notifications from various sources, such as the system registry or an SNMP device. Using the application adapters, management applications written with various programming interfaces can access the CIMOM object repository without having to be rewritten.

Built-in providers

The built-in providers supply CIM Object Manager with information from various logical and physical sources such as the system registry, the Microsoft Win32® subsystem, and SNMP devices. The built-in providers include the following:

  • Performance Monitor provider
  • Registry provider
  • Registry event provider
  • SNMP provider
  • Windows event log provider
  • Win32 provider
  • WDM Provider

Events

Any practical management application must be largely driven by events. This is true both for reactive management (such as fixing something after it breaks) and preventive management (such as fixing something before it breaks). Events represent interesting occurrences within the managed environment. WMI supports the detection of events and the delivery of these events to interested subscribers.

Any event architecture has to solve at least three quite different problems:

  • Publication
    How do I find out what events there are?
  • Subscription
    How do you tell the system that you are interested in an event?
  • Delivery
    How does the event get delivered to you?

In WMI, a client application subscribes to an event by creating a query. Queries are a natural way to interact with a class and allow you to tell WMI which event or events you are interested in.

The access to WMI management information and APIs in .NET is provided through the System.Management namespace.

WMI categorizes events into intrinsic, extrinsic, and timer events.

  • Intrinsic events
    These are events generated by WMI in response to internal changes in data; for example, when class instances are created, modified, or deleted. WMI obtains information about intrinsic events from the CIM Repository.
  • Extrinsic events
    These represent user-defined events that are not already described by an intrinsic event.
  • Timer events
    These are events that occur either at a particular time or repeatedly at regular intervals. Unlike intrinsic and extrinsic events, for timer events to occur, they must be established explicitly by consumer applications.

Event delivery

WMI allows you to specify which events are to be delivered to you, and what data is to be delivered with each event. The following example illustrates how to obtain the name of a manually started service each time it is stopped.

The first step is to locate a class that models the object to be monitored—in this case, a Win32 service. You can view classes and examine methods and properties using the CIM Studio tool that is supplied with the WMI SDK. If you view the Win32_Service class within CIM Studio, you will locate the StartMode property. CIM Studio also allows you to right-click a property name and to examine the range of possible values that can be maintained by the property. The StartMode property supports the Manual and Automatic values. The name of the service is provided by the Name property, so the subscription query would be as follows:

Select TargetInstance.Name
From __InstanceModificationEvent
Within 10
Where TargetInstance isa 'Win32_Service' and
    TargetInstance.StartMode = 'Manual' and
    TargetInstance.Started = FALSE and
    PreviousInstance.Started = TRUE

Notice that the query uses the PreviousInstance value to determine whether the service was previously running and has now been stopped. The query uses the Within clause to define a polling interval to be used by the Object Manager in detecting the occurrence of the event every 10 seconds. You can determine the difference between events that are provided by an event provider versus events manufactured by WinMgmt by polling a certain piece of data and comparing it against the defined event query.

Event subscriptions

WMI provides the necessary infrastructure to support both the detection of events and their delivery to interested subscribers. WMI comes with a variety of standard subscribers that you can use to build sophisticated event handlers. For example, WMI can make use of Microsoft Message Queuing (MSMQ) to provide reliable delivery for events. It also includes standard subscribers that can issue command line calls that, for example, allow you to send an e-mail message when an event occurs.

While WMI can detect some events by itself, such as changes to the Common Information Model (CIM) repository, most events are detected for WMI by event providers. Event providers are WMI providers that monitor a source of events and notify WMI when events occur. Examples include the Simple Network Management Protocol (SNMP) trap provider, Windows Event Log provider, and the Registry Event provider (which notifies WMI when a registry entry changes).

WMI consumers subscribe to selected events. There are two types of event subscriptions in WMI; temporary and permanent. The following defines these types of event subscriptions:

  • Temporary
    These event subscriptions are created by applications that subscribe to certain events. These subscriptions exist only while the consumer application is running. Therefore, temporary subscriptions are canceled as the subscribing application shuts down and the subscription is removed when consumer terminates.
  • Permanent
    These event subscriptions are created by subscription builders to have a certain action performed every time an event occurs. Unlike temporary subscriptions, permanent subscriptions are stored in the CIM repository and remain active until explicitly removed by the subscription builder. The subscription builder cancels a permanent subscription by removing its objects from the CIM repository. You could create a permanent event subscriber so that when the event occurs, WMI would notify you using the subscription. For example, you could make sure that an operator is notified every time a particular service is stopped. In the case of a permanent subscription, the consumer can be invoked (loaded) by WinMgmt when the event occurs (if it is not running at the time).

The filtering of events is done in process to the event source, such that if no one is subscribed for a certain event the event gets dropped in process and there is no cross-process activity or overhead on WinMgmt or the consumer.

For more information, see the Windows Management Instrumentation (WMI) SDK.

Instrumenting .NET Applications

Instrumentation is the process of adding management events, performance counters, and trace information to an application to allow monitoring tools to track the current health and performance characteristics of the application. You may also choose to expose classes to allow your application to be configured through WMI. You can instrument an application to:

  • Support performance analysis and runtime profiling.
  • Support problem diagnosis.
  • Support application configuration.

.NET provides a series of classes that help you instrument your application. These classes serve to further abstract the underlying detail of the WMI implementation.

Adding Instrumentation to .NET Applications

The System.Management.Instrumentation namespace minimizes the work required to make an application manageable through WMI and also helps an application generate WMI events. Specifically, this namespace provides types to allow you to:

  • Instrument an application.
  • Expose application (delegate-based) events as WMI events.
  • Create manageable objects.
  • Define and use relationships between manageable objects.

Exposing an application's objects for management should be intuitive for .NET programmers because the WMI schema is object-oriented and has many traits in common with .NET metadata. Because an application's objects can be mapped directly to WMI objects, it is relatively easy to instrument managed code applications. For example, you could use instrumentation within your .NET application to:

  • Send events from components within your application.
  • Provide manageable objects to facilitate application configuration.
  • Expose runtime data; for example, performance characteristics.

If you provide this type of instrumentation within your application, you can greatly assist problem diagnosis and quickly alert operators to conditions that require immediate attention. It is also possible to develop event subscribers that can provide automated responses to problem situations. Performance metrics can be used to locate bottlenecks within your applications and diagnose problems associated with application topology.

.NET base class support

The .NET Framework Class Library (FCL) provides the System.Management.Instrumentation namespace to help instrument .NET applications. The System.Diagnostics namespace also provides support for developing custom performance counters. Finally, the System.Management namespace provides a set of managed-code classes through which .NET applications can easily access and manipulate management information. For more information about these classes, refer to the Monitoring and Supporting .NET Applications section of this article.

Figure 3 identifies the three tiers of the WMI architecture and how .NET clients, such as Win Form and Web Form applications, can easily and intuitively access WMI instrumentation using the System.Management classes. It also shows how instrumented .NET applications use classes within the System.Management.Instrumentation namespace to raise events and expose management data.

Ee957925.monitordotnet04(en-us,MSDN.10).gif

Figure 4. WMI Architecture in .NET

Using .NET attributes

You can use .NET attributes to declaratively expose custom application events and classes, thus making them manageable through WMI. This approach is beneficial in that it requires little additional coding. When you mark a class as manageable using the .NET attributes, you establish a mapping to the WMI schema. You can also derive your own event classes from the BaseEvent class located in the System.Management.Instrumentation namespace.

Once you have instrumented your application, it is manageable through WMI. Objects and events can be discovered, monitored, and configured. The managed-code events marked for management are automatically fired as WMI events. The code objects marked for management are registered with WMI as instances of WMI classes, complete with their properties and methods. In addition, references between the code objects map to WMI associations, allowing for rich relationship discovery and traversal.

Exposing events

You may want to use an event to notify operators of a specific condition. There are two ways to expose WMI events:

  • You need to define a class for an event. If a managed code class within your application already has an event (based on the delegate model) defined for it, and that event could also be used as an administrative event, you need to only mark that event for management using a .NET Framework attribute. As a result of the attribute, a system provided event handler is connected to the event. This handler implementation fires a WMI event, mapping all the information obtained from the code event into properties of the WMI event.
  • Define a new class derived from BaseEvent. If you derive from BaseEvent, there is a Fire method on this base class that one can use to fire the event. If for some reason you don't want or cannot derive your event class from this base class, you can use the Instrumentation helper class to call the static Fire method and pass it the object to be fired.

The following C# code provides an example of the second approach and demonstrates how to define a new class to represent an event and then fire it using the Instrumentation class:

using System;
using System.ComponentModel;
using System.Management.Instrumentation;
[assembly:Instrumented("root\\MyDemo")]

[System.ComponentModel.RunInstaller(true)]
public class MyProjectInstaller:DefaultManagementProjectInstaller
{
}

[InstrumentationClass(InstrumentationType.Event)]
// Management instrumentation event classes derive from
// the BaseEvent class
public class MyBaseEvent : BaseEvent
{
   private string message;
   private int number;
   // Define properties
   public string Message {
      get { return message; }
      set { message = value; }
   };
   public int Number {
      get { return number; }
      set { number = value; }
   }
}

public class TestWMI
{

   public static void Main()
   {
      MyBaseEvent ev = new MyBaseEvent();
      ev.Message = "This is a test event...";
      ev.Number = 12345;
// Fire the event using the static Fire method of       
// the system provided Instrumentation class
      ev.Fire();
   }
}

.NET provides the provider instrumentation for you and auto deploys if you run Installutil.exe after application deployment (through MSI custom setup action or through .NET Xcopy deployment, which requires manual execution of the .exe file).

Alternatively, if you'd rather not use the InstallUtil utility, there is also a way to invoke the install step from your application the first time it is run. The disadvantage of this is that the schema for the objects that the application exposes appears in WMI only after the first time the application is run instead of immediately after it is installed.

The application schema is deployed in an MSI custom action where you run Installutil.exe or through Xcopy; otherwise, the schema is not deployed and events will not be fired or consumed.

The code example defines the MyBaseEvent managed-code class that derives from BaseEvent. The Main method in the TestWMI class instantiates the event, fills in the property values, and calls the Fire method of the Instrumentation class to fire the WMI event. This class can be discovered dynamically by walking the application's schema, and a developer can manipulate the class using regular WMI management services. Also, your members don't need to be properties—if they are public fields, they will also map to the WMI object.

Exposing data

In a data management scenario, you may want to expose one or more of your application's classes for management. To do this, you must define and implement the .NET class and then use the InstrumentedClass attribute to mark it for management. This automatically generates the WMI schema corresponding to the managed-code class. Instances of the class are exposed as WMI instances with all of the property values mapped, and even references between objects of the class and objects of other classes in the application are mapped to WMI associations (which are relationships between management objects defined in schema).

The following C# code example demonstrates how .NET Framework classes can be exposed as instrumentation data in the .NET Framework environment:

using System.Management;
[assembly:Instrumented("root\\default")]

[InstrumentationClass(InstrumentationType.Class]
public class Product
{
  public String Name;
  public int InstallDate;
  public int Version;
  public String Vendor;
}

The code example defines a Product class, which contains properties to define the Name, InstallDate, Version, and Vendor for applications in an enterprise. Through the use of attributes, WMI exposes this object and any developer can subsequently instantiate these objects and use WMI's built-in services such as discovery, querying, and filtering.

When an instance of this class is instantiated, it will not appear in WMI unless it is published. This gives you the ability to decide when the instance is "complete" and ready to be published. Typically, the publication should be the last step in the class constructor (after all initialization is completed). If you derive your class from the "Instance" base class, you can publish your instance by setting the Published property in this base class to "TRUE." If you don't derive from the base class, you can call Instrumentation.Publish.

Providing Performance Metrics

The mechanism by which Windows collects performance data on various system resources is the performance counter. A performance counter monitors the behavior of performance objects on a computer. These include physical components, such as processors, disks, and memory; and system objects, such as processes, threads, and application-specific metrics such as the time taken to complete an order placement transaction. Windows contains a pre-defined set of performance counters with which you can interact; some of these are found on all Windows 2000 computers while others are custom to specific applications and found only on certain computers. Each counter is related to a specific area of system functionality. Examples include counters that monitor a processor's busy time, memory usage, or the number of bytes received over a network connection.

Performance counters record values about various parts of the system. These values are not stored as entries, but are persisted for as long as the counter service remains in memory. The process of retrieving data from a performance counter is called sampling. When you sample, you either retrieve the immediate value of a counter or a calculated value.

.NET provides multiple built in performance counters including those that relate to the performance of the Common Language Runtime and those that relate to ASP .NET application performance.

ASP .NET profiling

ASP .NET exposes a series of global performance counters under the ASP .NET System performance counter object. These counters aggregate performance data for all of the ASP .NET applications running on a Web server, or within a Web farm. The type of information available from these counters include:

  • The number of applications running on a Web server.
  • The average request wait time.
  • The number of active sessions.
  • The number of times that an application has been restarted.

In addition, ASP .NET provides counters that provide performance data that relates to a specific instance of an ASP .NET application. This might be a Web form or a Web service application. The type of information available from these counters include:

  • The number of anonymous requests received.
  • The number of authenticated requests received.
  • Caching information, such as the ratio of cache hits to misses.
  • The number of compilations (for example, for .aspx or .asmx files).
  • The number of requests processed per second.
  • Session statistics, such as total session counts and timed out session counts.

The Web Application Stress (WAS) tool allows you to simulate multiple HTTP requests against a Web server. The WAS tool can be downloaded from the WAS tool Web site.

Creating custom performance counters

.NET provides classes within the System.Diagnostics namespace to support the creation of custom performance counters. For example, you could use a performance counter to measure an application round-trip. This represents the amount of time taken to service a client request and perform a transaction on behalf of the client. You might also want to measure performance of individual operations, such as the time taken to perform a credit card validation.

Specifically, the System.Diagnostics namespace contains the following types that relate to performance monitoring:

  • PerformanceCounter class
    This class handles both custom counters and system provided counters.
  • PerformanceCounterCategory class
    This class represents a category of performance counters.
  • PerformanceCounterInstaller class
    This class specifies an installer for a performance counter component.
  • PerformanceCounterManager class
    This class prepares performance counters for analysis.
  • PerformanceCounterType enumeration
    This enumeration is used to identify the type of performance counter, for example whether it is used to maintain an average performance metric, or whether it handlers an accumulated value, or whether it handles an elapsed time.

Using performance counters

The following are some of the ways to use performance counters:

  • They can be accessed through Windows supplied or custom developed applications.
  • They can be accessed using WMI interfaces and scripts.
  • They can be accessed by developers using COM interfaces, defined within the Platform SDK.

For more information about monitoring performance counters, refer to the Monitoring and Supporting .NET Applications section of this article.

Software Tracing

Application trace information is another useful source of data that can be used to help perform problem diagnosis. Developers often use tracing during system development, but it can also be extremely valuable for the operations team after the system has been deployed. It complements performance counters by providing information indicating when specific events occur. You can choose to either log text messages or log binary messages for subsequent post-processing to produce a human readable trace.

The System.Diagnostics namespace includes classes that provide trace support. The Trace and Debug classes within this namespace include static methods that can be used to instrument your code and gather information about code execution paths and code coverage. Tracing can also be used to provide performance statistics. To use these classes, you must define either the TRACE or DEBUG symbols, either within your code (using #define), or using the compiler command line.

By default, trace output is directed to the console. Classes are also provided to allow trace output to be easily redirected to the Windows event log. You can also create your own trace listeners to direct output to other locations.

ASP .NET tracing

ASP .NET provides sophisticated trace support. Performance data and custom trace messages can be appended as HTML output to the end of the returned HTML stream.

ASP provides the TraceContext class to maintain trace information. This includes timing details relating to the various stages within a page's lifecycle, together with custom messages. The TraceContext class is available through the Trace property of the Page class. Page level tracing can be controlled using the Trace attribute of the @Page directive, while application-level tracing can be controlled using settings within the application's Web.config file. For example, the following setting collects trace output for up to 20 requests, and enables trace statements written using Trace.Write from being output to the browser:

<configuration>
 <system.web>
  <trace enabled="true" requestLimit="20" pageOutput="true"/>
 </system.web>
</configuration>

Event tracing with WMI

WMI also supports event tracing. The volume and type of data, as well as where it will be stored, is controlled dynamically by WMI. To facilitate WMI support, you must define event trace classes within the CIM repository and then use the WMI event trace API. For more information about event tracing with WMI, refer to the WMI SDK documentation.

Using performance counters and event tracing

Event tracing is complementary to the use of performance counters. While counters have minimal system impact, making them ideal for constant application monitoring, it can be difficult to correlate between resources and workloads. For example, while performance counters help to identify bottlenecks within an application, event tracing can help you determine the cause of the bottleneck. When used together, these two approaches can be extremely powerful in diagnosing application and system performance issues.

WMI provides a consistent infrastructure for instrumenting an application. These basic steps will enable you to instrument an application.

Steps to instrument an application:

  1. Identify requirements.
  2. See if someone already makes it available. If they do, you're done.
  3. Figure out exactly where the information is coming from and make a list of the individual data items.
  4. Group the items in such a way that each group of items is dependent on one of the items in the group—this item is called the key.
  5. For each of the groups you identify, review the existing schema and see if the group already exists.
  6. Decide whether or not you can subclass the class.
  7. Design your schema.
  8. Decide what parts of your schema will be provided as data and what will be provided as events. These are not mutually exclusive:
    • Instance provider. If you have dynamic instances that come and go over time, you should implement an instance provider.
    • Event provider. If you need to provide an efficient implementation of event handling, you should implement an event provider.
  9. Define the .NET classes for these objects and events, and mark them appropriately with attributes. Instantiate and publish the data objects where needed in your application, and fire the events where appropriate.
  10. Test and deploy your instrumented application.

Examples:

// Class Definition Exposed as management metadata (schema)

using System.Management
[assembly:Instrumented("root\cimv2")]

[InstrumentationClass(InstrumentationType.Event)]
class Class PowerMgmtEvent : BaseEvent
{
         string ComputerName; // Machine where violation occurred
         datetime Time;    // Time of day of violation
         int Type;   // Enter suspend, resume from suspend
         // resume automatic, power status change
};


// Event is Fired from the Application

PowerMgmtEvent p = new PowerMgmtEvent();
ComputerName = "\\Mycomputer";    
      // Machine where violation occurred
Time = "";          // Time of day of violation
Type = 3;         // Enter suspend, resume from suspend
            // resume automatic, power status change
Fire();

Security

Providers will be required to load into a provider subsystem with the NetworkService security account. This account is intended for services that have no need for extensive privileges but have the need to communicate remotely with other systems. Using this account eliminates the potential risk that a corrupted or compromised provider could take out the entire computer (or domain, in the case of a domain controller). It also ensures that no privileged information is exposed to a user in case the provider does not properly impersonate the client's context. In general, hosting providers out-of-process assures that a faulting provider will affect only the providers in the same host and will not be able to affect the critical WinMgmt process. The provider host's lifecycle is fully controlled by WinMgmt. The latter automatically restarts the host if it exits for any reason. This effort increases WMI's robustness/reliability for applications that rely on key services that WMI provides.

Because the .NET instrumentation provider runs in process to the instrumented application, it uses a new WMI feature called the "decoupled provider." This is a special type of provider whose lifetime is controlled not by WMI, but rather by the host application. In addition, there is a difference in the security context this provider uses. Classic providers that are loaded and unloaded by WinMgmt and run in the controlled host are allowed and actually encouraged to impersonate the calling client when retrieving information for this client. In the decoupled provider case, because it's hosted in an application that can be run by any user, impersonation is not allowed, and only identify-level connection is supported. The provider always operates in the context of the user who is running the application, and performs an access check for the identity of the calling client before forwarding the management information requested. The decoupled provider also provides in the registration mechanism a security descriptor to define the users who are allowed to provide information for this application.

Instrumentation and N-Tier Applications

Large-scale distributed applications must deal with latency and access issues. Any practical distributed management application needs to have some substantial portion of the data used by the application available through a cache.

For example, this situation can occur in environments hosted by a perimeter network (also known as DMZ, demilitarized zone, and screened subnet) where front-end Web servers are located outside a firewall. These servers may be collecting and caching some management data that is periodically polled versus provided continually in real time. This is done to increase the security, and decrease chatter, through the firewall.

Maintenance of the cache implies the ability to discover the data sources, and query them in some way to build up the contents of the cache.

The following are some possible activities that may be involved in maintaining the cache:

  • Taking a snapshot
    Probably the best approach is to take a "fuzzy" snapshot of the system in which the complete system state is captured along with any changes to that state over the period of the snapshot; after the snapshot is complete, the changes are applied to the snapshot to bring it up to date.
  • Polling
    The cached data can be kept up to date by periodic polling. The cache maintenance system will periodically go to the data sources and capture any changes since the last poll with data being retrieved from the data source only if the data in the cache is older than the last change detected at the source.
  • Use of events
    The cached data can be kept current by registering for any relevant events at the data source. If WMI is available on the data sources and supports the efficient use of events, this approach should be considered as a preferable alternative to polling. This approach requires that the events are reliably delivered (for example, this can be achieved by using WMI eventing over Message Queuing); otherwise, the snapshot may get unsynchronized and with no periodic updates, the data becomes unreliable.
  • Polling and events
    It is also reasonable to mix polling and events by using events at the data source to capture relevant changes in the environment while using polling to gather the resulting deltas on a periodic basis. One of the biggest problems with periodic polling is that it implies a substantial impact on the performance of the data source when the data is gathered as presumably a large portion of the system's state has to be examined. Events have the advantage of spreading this load over a long period of time and limiting it to only those parts of the system state that have actually changed. The events themselves should be efficiently implemented and do not rely on polling.

Any large-scale distributed application also needs to allow for aggregation and filtering at each tier of the system if the system as a whole is to scale up effectively. WMI has natural mechanisms for expressing aggregated relationships through using providers and permanent event consumers. Consideration should be taken to determine efficient levels of duration, frequency, and granularity of management data.

Monitoring and Supporting .NET Applications

Monitoring applications are consumers of WMI events, and data can also use WMI to control and configure instrumented applications. As a consumer, you can:

  • Consume events.
  • Retrieve (or update) data.

A consumer makes requests to retrieve management data in one of the following ways:

  • Registering for events
  • Querying for a specific set of object instances
  • Enumerating instances or classes
  • Retrieving specific instances
  • Executing methods

The consumer is completely decoupled from the source of the data being provided. The consumer can be written in any language (C#, Managed C++, Visual Basic .NET, C/C++, Windows Script Host languages) and may be Win Form, Web Form, or Web service applications.

Consuming Management Information

Consuming management information is made easier by the classes provided within the System.Management namespace. Figure 3 illustrates Win Form and Web Form applications acting as WMI consumers. As a WMI consumer, a Win Form or Web Form client can monitor an application's health, operational status, and configuration. This functionality is supported by a set of rich WMI tools built-in to the Microsoft® Visual Studio® .NET development environment.

The System.Management namespace

The System.Management namespace provides various types to support WMI operations:

  • ManagementObject or ManagementClass
    A single management object or class, respectively.
  • ManagementObjectSearcher
    Used to retrieve a collection of ManagementObjects or ManagementClasses based on a specified query or enumeration.
  • ManagementEventWatcher
    Used to subscribe to event notifications from WMI.
  • ManagementQuery
    Used as the basis for all query classes.

.NET developers can use their current skills to access management information about computers or applications because WMI makes use of the standard base framework whenever appropriate. The coding paradigms for using the System.Management classes are natural to the .NET environment.

Consumption of management information is not only intended for management applications. Using System.Management, any application that needs to find out information about its operating environment. For example, an application needing to know as part of its own operation how much free disk space is available or whether a certain service it requires is running, can use System.Management to get this information.

The following C# code uses the System.Management collection classes to enumerate services on a computer. In this case, some defaults are used, so the root\cimv2 WMI namespace is used on the local computer. The example returns a collection of all objects for the specified class (Win32_Service). Following the retrieval of the collection, the client code enumerates through the collection using the foreach statement, and displays the name and state of each service in the collection—in two lines of code.

using System;
using System.Management;
using System.IO;

class WMI_Service_Example
{
   public void EnumerateServices
   {
Console.WriteLine("List services and their state");

//Request the collection of services
ManagementObjectSearcher s = new
ManagementObjectSearcher(new SelectQuery("Win32_Service"));   
   //Enumerate through the collection
   foreach (ManagementObject service in s.Get())
      Console.WriteLine("Service: "+service["Name"]+" is
      "+service["State"]);

   return;
    }
}

Handling WMI events

When a WMI event subscription is created, the subscriber must specify two things:

  • Which events the subscriber is interested in.
  • What the client requests WMI to do when the events occur.

The person or application creating the subscription is referred to as the subscription builder, and the code that actually receives the event is the event consumer.

By handling WMI events, you can perform specific actions when there is a change in the managed environment. For example, a subscription could be defined to link Consumer X with events A and B. In this case, Consumer X is notified each time A occurs and each time B occurs. There may be no relationship between events A and B. The following list represents some possible monitoring scenarios:

  • Statistical analysis scenarios
    Statistical analysis scenarios compile and store aggregated data about a business' activity. For example, an Internet portal may find it prohibitively expensive to log every event that occurs. It is reasonable, however, to log summary events, such as a daily Web usage summary, a daily usage summary for each URL, and a daily summary for each referring URL.
  • Health-monitoring scenarios
    In health-monitoring scenarios, certain types of events are not considered a problem until their frequency exceeds a specific level. For example, it is not considered a problem when a network device delivers several error events in an hour. It is worth noting and alerting the network administrators if the number of errors in an hour exceeds 100. Other health-monitoring scenarios include threshold and trend monitoring.
  • Policy condition scenarios
    Policy condition scenarios implement an appropriate policy when specified system conditions arise. For example, a cluster of two computers might have a policy that dictates that if one of the computers fails, the load should be automatically transferred to the other computer and the system administrator should be notified.

Writing a Temporary Event Consumer

The following C# code fragments illustrate a number of different temporary event consumers:

Monitoring the NT event log

// This code demonstrates how to monitor the NT event log for
// the arrival of new events
using System.Management;

WQLEventQuery q = new WQLEventQuery("InstanceCreationEvent",  
                         "TargetInstance ISA 'Win32_NTLogEvent'")

// Watch for NT Events in the NTEventLog
ManagementEventWatcher w = new ManagementEventWatcher(q);
w.EventArrived += h.EventArrived;
w.Start();
�
w.Stop();

// Define the event handler
public void EventArrived(Object sender, EventArrivedEventArgs e)
{
   //Get the Event object and display it
   Console.WriteLine("NTEvent "+e.Event["Message"]");
}
   

Monitoring Process CPU Utilization

// This code demonstrates how to monitor for processes that exceed
// 80% CPU utilization and then terminate them
ManagementEventWatcher w = new ManagementEventWatcher("SELECT * FROM 
__InstanceDeletionEvent WITHIN 4 WHERE TargetInstance ISA Win32_Process");
w.EventArrived += h.EventArrived;
w.Start();
�
w.Stop();

// Define event handler
public void EventArrived(Object sender, EventArrivedEventArgs e)
{
//Get the Event object and display it
   Console.WriteLine("Process " + e.Event["Message"] + 
             has terminated");

Monitoring Disk Space

WQLEventQuery q = new 
WQLEventQuery("__InstanceModificationEvent", "600", 
      "TargetInstance ISA 'Win32_LogicalDisk' AND 
      PreviousInstance.FreeSpace    >= 5000000 AND 
      TargetInstance.FreeSpace < 5000000")

//Watch for NT Events in the NTEventLog
ManagementEventWatcher w = new ManagementEventWatcher(q);
w.EventArrived += h.EventArrived;
w.Start();
�
w.Stop();

// Define event handler
public void EventArrived(Object sender, EventArrivedEventArgs e)
{
       //Get the Event object and display it
       Console.WriteLine("Disk " + e.Event["Name"] + 
                          is below 5MB of free space ");
}

Using Performance Monitor (PerfMon)

PerfMon is a system-provided tool that allows you to monitor either system or custom performance counters. When you connect to an existing performance counter, you do so by specifying the computer on which the counter exists, the category for the counter, and the name of the counter itself. Additionally, you have the option of specifying the instance of the counter you want to use, if the counter contains more than one instance. You can then read any and all data from the counter. You can also enumerate the existing categories, counters, and instances on the computer by using code.

Using Application Suites To Monitor

Application Management suites such as Microsoft Operations Manager (MOM) are able to monitor for errors and then respond with automatic notifications methods. It is important always to consider the possibility that one of these tools will be used to monitor your distributed applications. If management suites are present, consider their capabilities:

  • Most management suites roll up the individual server information into system-wide aggregations.
  • Most management suites show event logs and performance information across multiple servers on a single display.
  • Most modern management suites are based on WMI or provide their own management agents.

Microsoft is building the next-generation architecture for management services for Windows-based systems and the Microsoft Windows Server System™. The services will be built upon a foundation of existing management tools in the Windows 2000 operating system, the upcoming release of Systems Management Server, and the Microsoft Operations Manager (MOM). These three tools are designed to speed time to market, reduce the need for discrete management middleware, and offer greater ease of use throughout Windows-based applications.

Microsoft Application Center (AC)

Microsoft Application Center is the deployment and management tool for Windows-based Web applications. It allows users to easily deploy and manage Web applications across clusters of machines, including Web servers. It enables these applications to achieve on-demand scalability and mission-critical availability through software scaling, while also reducing operational complexity and costs. Application Center makes managing groups of servers as simple as managing one.

For more information, see the Microsoft Application Center.

Microsoft Application Center supports WMI. Application Center consumes and emits WMI events, allowing easier integration with other applications and system management tools that support WMI. Application Center includes Health Monitor with the following pre-configured thresholds to monitor system performance:

  • Integrated monitoring tools that roll up performance, events, and log data from across multiple servers into integrated console, allows drill down into specific machines and resources.
  • Self-healing and self-tuning systems by monitoring the health of servers and applications and by setting thresholds for acceptable performance.

Application Center, using Health Monitor, can collect system data, apply rules to that data, and perform actions (such as e-mail, programmatic action, create events) if rules are violated.

Application Center and WMI

Application Center and WMI work together in the following ways:

  • Applications can be written to provide WMI events that integrate with Application Center,
  • WMI providers in Application Center
    • Perf counters
    • Event Log
    • Service/Processes
    • COM+ applications
    • HTTP & FTP requests
    • ICMP, SMTP �

Microsoft Operations Manager (MOM)

Microsoft Operations Manager is a management application that utilizes WMI services. MOM provides centralized application management and system monitoring.

For more information, see the Microsoft Operations Manager Web site.

You can use Microsoft Operations Manager to:

  • Monitor distributed events, enterprise event logs, and handle distributed health monitoring.
  • Perform management scripting and Web-based monitoring.
  • Generate management reports, operator notifications and alerts.
  • Gather management information.

Microsoft Operations Manger includes event responses. For example, MOM can update a state variable, execute a command or batch file, or launch a script. In addition to responses, Microsoft Operations Manger can generate alerts. The following are examples of alerts:

  • Send e-mail.
  • Send a pager message.
  • Fire an SNMP trap.

Microsoft Operations Manager and WMI

Here are some examples of WMI Event Queries used in Microsoft Operations Manger:

State Change Events

  • The following checks every 10 minutes to see if any logical drive has fallen below 10 MB of free space:
    Select * from __instancemodificationevent WITHIN 600 
    WHERE TargetInstance ISA 'Win32_LogicalDisk' AND 
    TargetInstance.FreeSpace < 10000000 AND 
    PreviousInstance.FreeSpace > 10000000
  • Polling. Events come from monitoring changes in instance data.

System Events

  • The following sends an event when a power state event occurs in the system:
    Select * from Win32_PowerManagementEvent
    

    This event received is a Win32_PowerManagementEvent object. No polling is required; the event is driven from an actual notification.

Simple Network Management Protocol (SNMP)

  • SNMP traps are integrated with MOM via WMI. The WMI SNMP provider maps SNMP data into WMI. Events can be either based on SNMP traps or polling of SNMP data. In the following examples, you see that the registration of events with MOM is the same as for WMI.
  • Trap Example:
    Select * from SnmpLinkDownNotification
    
  • SNMP Data Example:
    Select * from __instancecreationevent WITHIN 60 WHERE 
    TargetInstance ISA 'SNMP_RFC1213_MIB_ipRouteTable'
    
  • If you need a standard RFC MIB, the WMI SDK already contains almost 40 already converted to MOF. If you need to use an enterprise MIB or one not in the SDK, convert the MIB to MOF using the SMI2SMIR tool that comes with the SNMP provider. Then follow these steps:
    1. Load the MOF into WMI using MOFCOMP.
    2. Configure the target device address, community string, and so on (per WMI SDK).
    3. Configure MOM to receive the traps/state changes as WMI events, as shown in the previous section.

Managed Object Format (MOF)

MOF is a compiled language used to define static or dynamic classes and class instances. You place these definitions in a text file that you submit to the MOF compiler, Mofcomp.exe. The MOF compiler parses the file and adds the classes and instances defined in the file to the Common Information Model (CIM) repository. For more information, see Managed Object Format (MOF) in the Platform SDK documentation.

Microsoft Systems Management Server (SMS)

SMS, Microsoft's existing change and configuration management solution, has been designed to make full use of Windows management services. SMS has a highly modular design that allows it to be used as a stand-alone solution or as an integrated part of a larger management solution.

For more information, see the Microsoft Systems Management Server Web site.

SMS provides comprehensive management of networked computers, including:

  • Hardware inventory based on WBEM.
  • Software distribution and installation.
  • Remote performance analysis and troubleshooting.
  • Network Tracing Topology Tool (NetTrace).
  • Network Monitor Tool (NetMon).

SMS and WMI

SMS uses WMI as the infrastructure on which to build its services. WMI allows you to monitor, configure, and control any manageable object through a common, unifying set of interfaces, regardless of the underlying instrumentation mechanism. SMS provides, among other benefits:

  • The SMS provider extends the WMI model to SMS-specific operations.
  • SMS has an event architecture that allows changes in management information to be identified, aggregated, compared to and associated with other management information, and forwarded to local or remote management applications. For example, you can query against the flow of status messages associated with the software distribution feature of SMS.

Third-party management tools

Microsoft will continue to enhance the range of Windows management services and will also continue to develop its own management solutions based on these services in areas key to customer satisfaction in Microsoft products. As described in this paper, this is only a small part of the overall opportunity to deliver management solutions to cover all the requirements of IT administrators.

The open availability of Windows management services will allow new levels of integrated management. It has the potential not only to integrate operations-based tools, but also to integrate them with service-level and business management tools and popular management platforms to create true enterprise management solutions.

In the past, third-party developers have had to spend considerable time developing the low-level frameworks necessary to support their respective management tools. This not only detracts from time that could have been spent on building the features of the management tools themselves, but it also limits the amount of integration possible between solutions, even when umbrella-style management solutions are in use. Using Windows management services, developers and solution providers can now concentrate on building management functions, rather than the underlying frameworks, knowing that the necessary infrastructure is freely available within the operating system itself.

Visual Studio .NET

The new features of Visual Studio .NET make it a complete development environment for building on the Microsoft .NET Framework. It includes tools such as Visual Studio Analyzer and Server Explorer that can be used to monitor your .NET applications.

Visual Studio .NET Server Explorer

Server Explorer is a tool window in Visual Studio .NET that can be used for browsing and manipulating management objects. It is also used to generate code in the context of Win Forms and Web Forms designers. Inside Visual Studio integrated development environment (IDE), Server Explorer nodes interact with the Property Browser and the component designer. This tool is intended to be used for browsing classes and instances, modifying property values, executing methods and generating managed code (through drag-and-drop). In contrast with CIM Studio, schema design is not addressed, and modifying WMI method signature is not allowed.

The Server Explorer window standard nodes do not use WMI. However, adding the Management Data and Management Events nodes, which provide access to the WMI data and allow event subscriptions, extends the standard functionality. The extension will be made available in future with Visual Studio .NET updates. You need this extension to have WMI functionality.

Server Explorer interaction with the component designer is through drag-and-drop operations. Certain nodes can be dragged into the form designer. When this happens, code is generated in the designed form, which references the component. In addition to the code generated in the form, another feature is the "strongly-typed objects code generator." This is a feature available programmatically through APIs on System.Management.ManagementClass, as well as through a command-line utility available in the .NET SDK called mgmtclassgen.exe or automatically through the drag-and-drop feature from Server Explorer. This feature generates a strongly typed managed code class for a given WMI class.

For instance, when invoked on the Win32_LogicalDisk WMI class, it will generate a managed code class called LogicalDisk, which contains all the properties and methods of the WMI class as first class properties as methods in it. The generated code is included in the application's project, and the user can now write strongly typed code to the WMI object, while taking advantage of all the Visual Studio developer assistance features such as statement completion. For example, instead of the "late-bound" System.Management code:

ManagementObject o = new ManagementObject("Win32_LogicalDisk='C:'");
Console.WriteLine(o["FreeSpace"]);

Or for invoking a method:

O.InvokeMethod("MethodFoo");

You can now write:

LogicalDisk d = new LogicalDisk("C:");
Console.WriteLine(d.FreeSpace);

And invoke the method with:

d.MethodFoo();

Simple Network Management Protocol (SNMP) support

SNMP is a management protocol used between management stations and agents. Management information is stored in a database called a Management Information Base (MIB).

The Windows Management Instrumentation SDK includes the following components to provide SNMP support:

  • Class, Instance, and Event Providers
  • SNMP Information Module Compiler

With the SNMP providers included in the Windows Management Instrumentation SDK, your client applications can access static and dynamic SNMP information through the CIM Object Manager. The SNMP Class and Instance Providers integrate the SNMP information modeling and processing into WMI.

  • These SNMP providers map collections of object values to property values of CIM class instances.
  • These Providers generate WMI events from SNMP traps and notifications. They report the same types of events, in different formats.

ActiveX Controls

The Windows Management Instrumentation SDK includes a set of ActiveX Controls that use the WMI APIs to perform logically related functions. You can use the ActiveX Controls to provide graphical user interface functionality in your WMI-based client applications.

Conclusion

When designing your .NET application, it is important to choose and implement an appropriate monitoring strategy early in the process. Your application should incorporate WMI-related features while it is being developed, tested, and deployed. Incorporating WMI will make your application extensible and provide rich information to developers and operators to properly monitor the health and performance of your application as well as manage the success of your application.

Collaborators

Many thanks to the following contributors and reviewers:

Travis Muhlestein, Corina Feuerstein, Michael Matson, Steve Busby, Kenny Jones, Jeff Kercher, Chris Brooks, David Keogh, Bart Robertson, Ann Chung, Edward Jezierski, Alex Mackman (Content Master), David Bernstein (Sapient), Bernard Chen (Sapient).

Questions? Comments? Suggestions? For feedback on the content of this article, please e-mail us at devfdbck@microsoft.com.

To learn more about .NET best practices, you can work side-by-side with technology experts at the Microsoft Technology Center in your area. For more information please visit the Microsoft Technology Centers Web page.

patterns and practices home

MSDN Magazine Blog

MSDN Magazine Right Rail

14 Top Features of Visual Basic 14: The Q&A
Leading off the feature in the January issue of MSDN Magazine is Lucian Wischik’s fantastic look at Visual Basic .NET 14. As Wischik writes, the newes... More...
Wednesday, Jan 7
Big Start to the New Year at MSDN Magazine
Folks, things are hopping over here at MSDN Magazine. We are kicking off the new year with a pair of issues: Our regularly scheduled January issue and... More...
Friday, Jan 2

More MSDN Magazine Blog entries >


Receive the MSDN Flash e-mail newsletter every other week, with news and information personalized to your interests and areas of focus.