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

Article translations Article translations
Article ID: 317336 - View products that this article applies to.
This article was previously published under Q317336
Expand all | Collapse all

On This Page

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.

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

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.

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 Sub
    End 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 Sub
    End Class
    					

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.

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")>
    					

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 Function
End 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 Sub
End Class
				

Module1.vb

Imports System.EnterpriseServices

Module 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 Sub

End Module
				

AssemblyInfo.vb

Imports System.Reflection
Imports 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.*")>
				

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.

Troubleshooting

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

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

Properties

Article ID: 317336 - Last Review: July 15, 2004 - Revision: 4.4
APPLIES TO
  • Microsoft .NET Framework Class Libraries 1.0
  • Microsoft Enterprise Services (included with the .NET Framework) 1.0
  • Microsoft Visual Basic .NET 2002 Standard Edition
Keywords: 
kbhowtomaster KB317336

Give Feedback

 

Contact us for more help

Contact us for more help
Connect with Answer Desk for expert help.
Get more support from smallbusiness.support.microsoft.com