How To Use Enterprise Services Object Pooling in Visual Basic .NET

This article was previously published under Q317336
This article has been archived. It is offered "as is" and will no longer be updated.
SUMMARY
This article demonstrates how to create a console application that uses object pooling in Visual Basic .NET. You can turn on and turn off object pooling to see how object pooling affects an application that creates many expensive objects.

back to the top

Requirements

The following list outlines the recommended hardware, software, network infrastructure, and service packs that you need:
  • Microsoft .NET Framework
  • Microsoft Windows 2000 Professional, Microsoft Windows 2000 Server, Microsoft Windows XP Professional, or Microsoft Windows XP Server
This article assumes that you are familiar with the following topics:
  • Component Object Model (COM) and Enterprise Services
  • Object pooling
  • Using attributes to extend metadata
back to the top

Create a Console Application in Visual Basic .NET

  1. Start Microsoft Visual Studio .NET.
  2. On the File menu, point to New, and then click New Project.
  3. In the New Project dialog box, click Visual Basic Projects under Project Types, and then click Console Application under Templates.
  4. In the Name text box, type PoolingDemo, and then click OK.
  5. Make sure that the Solution Explorer window is visible. If Solution Explorer is not visible, press the CTRL+ALT+L key combination.
  6. Follow these steps to add a reference to the COM component that you will be using:
    1. In Solution Explorer, right-click References, and then click Add Reference.
    2. On the .NET tab, click System.EnterpriseServices in the list of available components, and then click Select. Notice that System.EnterpriseServices appears in the Selected Components list.
    3. Click OK. Notice that System.EnterpriseServices appears under the References node in the console application.
back to the top

Add a Poolable and a Non-Poolable Class to the Project

  1. Right-click PoolingDemo in Solution Explorer, point to Add, and then click Add New Item.
  2. In the Add New Item dialog box, click Class under Templates, and then click Open. Class1.vb is created by default and contains both poolable and non-poolable classes.
  3. To access object pooling attributes and members, add the following code to the top of Class1.vb:
    Imports System.EnterpriseServices					
  4. Replace the default Class1 declaration with the following code:
    Public Class Poolable    Sub New()        Threading.Thread.Sleep(500)    End Sub    Public Sub DoSomething()        ' Add method contents here.    End SubEnd Class						
    Notice that the constructor contains code that simulates an expensive operation.
  5. The object must inherit the ServicedComponent class to come under the control of the Component Services runtime. Add the following code after the class declaration:
    Inherits ServicedComponent					
  6. To make this class poolable, follow these steps:
    1. The ObjectPoolingAttribute attribute, which is saved with the metadata of the class file, flags the object for pooling at run time. Add the following code above the Class declaration to add the ObjectPoolingAttribute attribute to the class:
      <ObjectPooling(MinPoolSize:=0, MaxPoolSize:=1), JustInTimeActivation(True)>  _  							
      NOTE: Although the JustInTimeActivation attribute is not required to enable pooling, you may want to use this attribute in most cases. Because it is expensive to create and to discard components, you can improve performance significantly by allowing multiple clients to reuse component instances.
    2. The CanBePooledServicedComponent method returns False by default. To override the CanBePooled method so that the method returns True, add the following code:
      Protected Overrides Function CanBePooled() As Boolean        Return True    End Function						
  7. Add the following code to the non-poolable class:
    Public Class NonPoolable    Inherits ServicedComponent    Sub New()        ' Simulate an expensive operation.        Threading.Thread.Sleep(500)    End Sub    Public Sub DoSomething()        ' Add method contents here.    End SubEnd Class					
back to the top

Modify Module1.vb to Create Multiple Instances of These Classes

  1. In the Code Editor window, click the Module1.vb tab.
  2. At the top of the file, add the following Imports statement for the EnterpriseServices namespace to allow access to the DisposeObject method:
    Imports System.EnterpriseServices						
    The DisposeOjbect method returns objects to the object pool, which allows them to be reused.
  3. Add the following Sub Main procedure:
    Sub Main()        Dim StartTime As DateTime = DateTime.Now        Dim i As Int32        Const Iterations As Int16 = 50        For i = 1 To Iterations            Dim D As New NonPoolable()            D.DoSomething()            ServicedComponent.DisposeObject(D)        Next        Dim EndTime As DateTime = DateTime.Now        Dim Elapsed As TimeSpan = EndTime.Subtract(StartTime)        Dim OperationsPerSecond = Iterations / Elapsed.TotalSeconds        Console.WriteLine("Object Creations / Second = " & OperationsPerSecond)        System.Console.ReadLine()End Sub						
    This code sets up a loop that creates an instance of the NonPoolable or the Poolable class during each of its 50 iterations. The code records the start and the end times for the loop and then writes the number of objects that are created per second to the console.
back to the top

Generate a Strong Name for the Assembly

You must generate a strong name for the assembly that this project will generate. Without a strong name, you cannot use COM+ services to register this assembly.

To generate this cryptographic key pair, use the Strong Name (Sn.exe) tool, which is located in the Bin folder where the .NET Framework Software Development Kit (SDK) is installed. Use the following command-line syntax to run the Sn.exe tool:
sn -k drive letter\DirectoryToPlaceKey\KeyName.snk
  1. To open a Visual Studio .NET command prompt, click Start, point to Programs, point to Microsoft Visual Studio .NET, point to Visual Studio .NET Tools, and then click Visual Studio .NET Command Prompt.
  2. At the command prompt, type the following command:
    sn -k drive letter:\Project Root Folder\poolkey.snk
  3. Press the ENTER key to generate the key pair. Notice that the following message appears in the command window:
    Key pair written to...
  4. To associate this key with the project's assembly, double-click AssemblyInfo.vb in Solution Explorer. By default, Visual Studio .NET includes assembly attributes in this file when you create a project. Add the following code to this list of assembly attributes:
    <Assembly: AssemblyKeyFile("..\..\poolkey.snk")>					
back to the top

Complete Code Listings

Class1.vb

Imports System.EnterpriseServices<ObjectPooling(MinPoolSize:=0, MaxPoolSize:=1), JustInTimeActivation(True)>  _Public Class Poolable    Inherits ServicedComponent    Sub New()        ' Simulate an expensive operation.        Threading.Thread.Sleep(500)    End Sub    Public Sub DoSomething()        ' Add method contents here.    End Sub    Protected Overrides Function CanBePooled() As Boolean        Return True    End FunctionEnd ClassPublic Class NonPoolable    Inherits ServicedComponent    Sub New()        ' Simulate an expensive operation.        Threading.Thread.Sleep(500)    End Sub    Public Sub DoSomething()        ' Add method contents here.    End SubEnd Class				
back to the top

Module1.vb

Imports System.EnterpriseServicesModule Module1    Sub Main()        Dim StartTime As DateTime = DateTime.Now        Dim i As Int32        Const Iterations As Int16 = 50        For i = 1 To Iterations            'Dim D As New Poolable()            Dim D As New NonPoolable()            D.DoSomething()            ' To return the object to the object pool, use DisposeObject.            ' This allows the object to be reused from the pool. If you do not call            ' DisposeObject, the garbage collector does not collect this object,             ' and the object is not reused from the object pool.            ServicedComponent.DisposeObject(D)        Next        Dim EndTime As DateTime = DateTime.Now        Dim Elapsed As TimeSpan = EndTime.Subtract(StartTime)        Dim OperationsPerSecond = Iterations / Elapsed.TotalSeconds        Console.WriteLine("Object Creations / Second = " & OperationsPerSecond)        ' Pause until the user presses ENTER.        System.Console.ReadLine()    End SubEnd Module				
back to the top

AssemblyInfo.vb

Imports System.ReflectionImports System.Runtime.InteropServices' The following set of attributes control general information about an assembly. ' Change these attribute values to modify the information that is associated with an assembly.' Review the values of the assembly attributes.<Assembly: AssemblyTitle("")> <Assembly: AssemblyDescription("")> <Assembly: AssemblyCompany("")> <Assembly: AssemblyProduct("")> <Assembly: AssemblyCopyright("")> <Assembly: AssemblyTrademark("")> <Assembly: CLSCompliant(True)> <Assembly: AssemblyKeyFile("..\..\poolkey.snk")> 'The following GUID is for the ID of the TypeLib if you expose this project to COM.<Assembly: Guid("30324ED6-329C-4B12-BDA2-8E817F1E2079")> ' Version information for an assembly consists of the following four values:''      Major Version'      Minor Version '      Build Number'      Revision'' You can specify all of these values, or you can use the asterisk (*) for' the Build Number and the Revision values.<Assembly: AssemblyVersion("1.0.*")>				
back to the top

Verify That It Works

  1. Press the F5 key to run the application in debug mode. Notice that this creates instances of the NonPoolable class.
  2. Wait approximately 25 seconds. Notice that the following message appears:
    Object Creations / Second = 1.73542243764044
    NOTE: The exact number of creations per second may vary.
  3. Press ENTER to exit the console application and to return to Visual Studio .NET.
  4. Modify Module1.vb to create instances of the Poolable class. Change the first line in the Sub Main procedure as follows:
    Dim D As New Poolable()					
  5. Press F5 to run the application again.
  6. Wait a few seconds. Notice that the following message (or similar) appears:
    Object Creations / Second = 29.1977213631085
    Note the significant improvement in performance when you use object pooling.
  7. Press ENTER to exit the console application and to return to Visual Studio .NET.
back to the top

Troubleshooting

Do not forget to override CanBePooled. If you omit this step, you cannot pool the object.

back to the top

REFERENCES

For more information about how to implement and deploy COM+ configured classes by using the common language runtime, how to access object context and call context, and how to manage context-relative object references, refer to the following Microsoft Web site:
COM+ Integration: How .NET Enterprise Services Can Help You Build Distributed Applications
http://msdn.microsoft.com/en-us/library/bb985615.aspx
back to the top
Properties

Article ID: 317336 - Last Review: 01/11/2015 04:32:40 - Revision: 4.4

  • Microsoft .NET Framework Class Libraries 1.0
  • Microsoft Enterprise Services (included with the .NET Framework) 1.0
  • Microsoft Visual Basic .NET 2002 Standard Edition
  • kbnosurvey kbarchive kbhowtomaster KB317336
Feedback