Apply Your Knowledge
Exercises
Exposing Serviced Components via .NET Remoting
In an enterprise application, you may be required to expose business objects remotely. A general practice in that case is to add an extra tier that handles remote communication between the client and server. You can use your knowledge of .NET remoting and XML Web services for creating such a tier.
In this exercise, you learn how to expose a serviced component via a remoting server. You create three sets of programs: a serviced component that allows access to the Northwind database, a Singleton remoting server that exposes the serviced component, and a client program that connects to the remoting server to invoke methods on the serviced component.
Estimated Time:
30 minutes.
Launch Visual Studio .NET. Select File, New, Blank Solution, and name the new solution 320C07Exercises. Click OK. Add a new Visual C# .NET Class library project named Exercise7_1SC to the solution. In the Solution Explorer, right-click project Exercise7_1SC and select Add Reference from the context menu to add a reference to the System.EnterpriseServices component. In the Solution Explorer, rename the default Class1.cs to NorthwindSC.cs. Open the NorthwindSC.cs and replace the code with the following code (change the Guid attribute):
using System;
using System.Data;
using System.Data.SqlClient;
using System.EnterpriseServices;
using System.Runtime.InteropServices;
using System.Diagnostics;
namespace Exercise7_1SC
{
public interface INorthwind
{
DataSet ExecuteQuery(
string strQuery);
int UpdateData(
string strQuery, DataSet ds);
}
[EventTrackingEnabled(true)]
[JustInTimeActivation(true)]
[ObjectPooling(true, 2,4)]
[Guid(
"94AB3102-C44F-40de-A29F-309437D9EC86")]
[ClassInterface(
ClassInterfaceType.None)]
public class NorthwindSC :
ServicedComponent, INorthwind
{
private SqlConnection sqlcnn;
private SqlDataAdapter sqlda;
private DataSet ds;
private EventLog eventLog;
public NorthwindSC()
{
// Create a connection to the
// Northwind SQL Server database
sqlcnn = new SqlConnection(
"data source=(local);" +
"initial catalog=Northwind;" +
"integrated security=SSPI");
// Create an EventLog object
// and assign its source
eventLog = new EventLog();
eventLog.Source = "Exercise7_1";
// Write an entry to the event log
eventLog.WriteEntry("A new " +
"NorthwindSC object is created " +
" and added to the object pool");
}
protected override void Activate()
{
eventLog.WriteEntry(
"A NorthwindSC object is " +
"activated from the object pool");
}
protected override void Deactivate()
{
eventLog.WriteEntry(
"A NorthwindSC object is " +
" deactivated and is " +
"returned to the object pool");
}
protected override bool
CanBePooled()
{
return true;
}
public DataSet ExecuteQuery(
string strQuery)
{
// Create a SqlDataAdapter object
// to talk to the database
sqlda = new SqlDataAdapter(
strQuery, sqlcnn);
// Create a DataSet object
// to hold the results
ds = new DataSet();
// Fill the DataSet object
sqlda.Fill(ds, "Results");
// Deactivate the object
// when the method returns
ContextUtil.DeactivateOnReturn
= true;
return ds;
}
[AutoComplete]
public int UpdateData(
string strQuery, DataSet ds)
{
// Update the database
sqlda = new SqlDataAdapter(
strQuery, sqlcnn);
SqlCommandBuilder sqlcb =
new SqlCommandBuilder(sqlda);
return sqlda.Update(
ds.Tables["Results"]);
}
}
}
Open the AssemblyInfo.cs file in the project and add the following using directive:
using System.EnterpriseServices;
Add the following assembly-level attributes in the AssemblyInfo.cs file:
[assembly: ApplicationName(
"Northwind Data Application " +
"exposed via Remoting")]
[assembly: Description(
"Retrieve and Update data " +
"from the Northwind database")]
[assembly: ApplicationActivation(
ActivationOption.Server)]
Copy the 70320.snk key pair file to the 320C07Exercises folder. Change the AssemblyVersion and AssemblyKeyFile attributes in the AssemblyInfo.cs file as shown here:
[assembly: AssemblyVersion("1.0")]
[assembly: AssemblyKeyFile(@"..\..\..\70320.snk")]
Build the project. An Exercise7_1SC.dll file is generated, and a strong name is assigned to the file based on the specified key file. Launch the Visual Studio .NET command prompt and change the directory to the folder where the DLL file generated in step 8 resides. Issue the following command to install the assembly to the GAC:
gacutil /i Exercise7_1SC.dll
At the command prompt, issue the following command to install the service component assembly to the COM+ Catalog:
regsvcs Exercise7_1SC.dll
Add a new Visual C# .NET Console application named Exercise7_1Server to the solution. In the Solution Explorer, right-click project Exercise7_1Server and select Add Reference from the context menu to add references to the System.Runtime.Remoting, System.EnterpriseServices, and Exercise7_1SC components. In the Solution Explorer, rename the default Class1.cs to NorthwindSCServer.cs. Open the file and change the name of the class to NorthwindSCServer in the class declaration. Add the following using directives:
using System.Runtime.Remoting;
using System.Runtime.Remoting.Channels;
using System.Runtime.Remoting.Channels.Tcp;
Add the following code in the Main() method:
[STAThread]
static void Main(string[] args)
{
// Create and Register a TCP
// server channel that
// listens on port 1234
TcpServerChannel channel =
new TcpServerChannel(1234);
ChannelServices.RegisterChannel(
channel);
// Register the service that
// publishes NorthwindSC for
// remote access in Singleton mode
RemotingConfiguration.
RegisterWellKnownServiceType
(typeof(Exercise7_1SC.NorthwindSC),
"NorthwindSC",
WellKnownObjectMode.Singleton);
Console.WriteLine(
"Started server " +
"in the Singleton mode");
Console.WriteLine(
"Press <ENTER> to " +
"terminate server...");
Console.ReadLine();
}
Build the project. This step creates a remoting server that is capable of registering the Exercise7_1SC.NorthwindSC serviced component for remote invocation in the SingleCall activation mode. Add a new Visual C# .NET Windows application named Exercise7_1Client to the solution. Add references to the .NET assemblies System.Runtime.Remoting and System.EnterpriseServices and the project Exercise7_1SC (the serviced component class assembly). Add the following using directives:
using System.Runtime.Remoting;
using System.Runtime.Remoting.Channels;
using System.Runtime.Remoting.Channels.Tcp;
using Exercise7_1SC;
Place two GroupBox controls, a TextBox control (txtQuery), two Button controls (btnExecute and btnUpdate), and a DataGrid control (dgResults) on the form. Arrange the controls as shown in Figure. Double-click the form and add the following code in the Load event handler:
private void NorthwindSCClient_Load(
object sender, System.EventArgs e)
{
// Register a TCP client channel
TcpClientChannel channel =
new TcpClientChannel();
ChannelServices.RegisterChannel(
channel);
// Register the remote class as a valid
// type in the client's
// application domain
RemotingConfiguration.
RegisterWellKnownClientType(
// Remote class
typeof(NorthwindSC),
// URL of the remote class
"tcp://localhost:1234/NorthwindSC"
);
}
Double-click the Button controls and add the following code in their Click event handlers:
private void btnExecute_Click(
object sender, System.EventArgs e)
{
// Declare and instantiate
// the remote serviced component
NorthwindSC nsc= new NorthwindSC();
try
{
// Call the ExecuteQuery() method
dgResults.DataSource =
nsc.ExecuteQuery(txtQuery.Text);
dgResults.DataMember = "Results";
}
catch(Exception ex)
{
MessageBox.Show(ex.Message,
"Invalid Query",
MessageBoxButtons.OK,
MessageBoxIcon.Error);
}
}
private void btnUpdate_Click(
object sender, System.EventArgs e)
{
// Declare and instantiate
// the remote serviced component
NorthwindSC nsc= new NorthwindSC();
try
{
// Call the UpdateData() method
int intRows = nsc.UpdateData(
txtQuery.Text,
(DataSet) dgResults.DataSource);
MessageBox.Show(String.Format(
"{0} row(s) updated", intRows),
"Row(s) Updated",
MessageBoxButtons.OK,
MessageBoxIcon.Information);
// Load the updates and bind the
// grid with the updates
dgResults.DataSource =
nsc.ExecuteQuery(txtQuery.Text);
dgResults.DataMember = "Results";
}
catch(Exception ex)
{
MessageBox.Show(ex.Message,
"Update Failed",
MessageBoxButtons.OK,
MessageBoxIcon.Error);
}
}
Build the project. Start the remoting server and then start the client. Enter some queries to retrieve data from the Northwind database to test your programs.
Using Application Pooling and Recycling
Application pooling allows more than one instance of the COM+ server application to run at a time. By default, the size of the application pool is 1. If you set this size to a higher value, for Figure, then the first four activation requests to the application create four instances of dllhost.exe, each running this application. Later requests for applications are then routed through this pool of dllhost.exe processes. Application activation increases the scalability of the application and provides support for application failover.
Using the automatic application recycling service, you can configure an application to shut down and restart automatically when known problems occur. Some of the criteria for which you can configure recycling include lifetime limit, memory limit, call limit, and so on.
Both application pooling and recycling are features of COM+ 1.5. Currently the .NET Framework SDK does not provide any attribute to configure these services in your program. If you need to configure these services in a program, you must instead rely on the COM+ Administrative SDK.
However, you can also use the Component Services administrative tool to administratively configure these services. In this exercise, you learn how to configure application pooling and recycling on a machine running COM+ 1.5 (that is, Windows XP and Windows .NET Server computers).
Estimated Time:
10 minutes.
Open the Component services administrative tool. Right-click the Ordering Application icon and select Properties from the shortcut menu. In the Ordering Application Properties dialog box, select the Pooling & Recycling tab, as shown in Figure.

Set the Pool Size to 4, Lifetime limit to 5 minutes and the Call Limit to 10. Apply the changes. Start the order form and place a few orders. In the list of the running processes, you will see that multiple instances of dllhost.exe are created for the Ordering Application, and if you wait for 5 minutes or place 10 orders, then a new dllhost.exe process is started.
Review Questions
| 1: | What is the COM+ catalog and what is it used for? | |
A1:
| The COM+ Catalog is a repository that is used by COM+ to store the information about the serviced components and their runtime requirements. | | 2: | What is the significance of using the AutoComplete attribute in a method declaration? | |
A2:
| Using the AutoComplete attribute in a method declaration is the equivalent of writing code to call ContextUtil.SetComplete() or ContextUtil.SetAbort(), respectively, when a method successfully completes or completes with an error. | | 3: | What is the use of the CanBePooled() method for a pooled object? | |
A3:
| When a pooled object is about to be deactivated, the CanBePooled() method is called to check whether the object should be returned to the object pool or instead destroyed. An object is returned to the object pool only when the CanBePooled() method returns true. | | 4: | How does a client instantiate a queued component? | |
A4:
| To instantiate a queued object, the client uses the Marshal.BindToMoniker() method. This method accepts a moniker name that identifies the target queued component. This method then instantiates a recorder for the queued component. The client can record all the calls on this recorder. When the queued component becomes available, the recorded calls are played back to the queued component. | | 5: | How can you use COM+ services to increase an application's throughput? | |
A5:
| You should use the COM+ just-in-time activation and object pooling services for the following reasons:
JIT activation enables clients to hold long-lived references on the server object (through a proxy) without consuming server resources. JIT activation allows the server objects to be destroyed as soon as their work is finished to minimize the resource consumption on the server. Object pooling caches the already-created objects and saves time by activating and deactivating the objects from the pool instead of re-creating them from scratch.
| | 6: | How would you specify the type of transaction available to a serviced component? | |
A6:
| The Transaction attribute can be used to specify the type of transaction available to a component. This is done by setting its value to one of the TransactionOption values—Disabled, NotSupported, Required, RequiresNew, and Supported. | | 7: | What is the use of the ContextUtil class? | |
A7:
| The ContextUtil class provides several methods and properties to obtain information about the COM+ object contexts. | | 8: | What are some of the scenarios where you might want to use the COM+ object pooling service? | |
A8:
| Scenarios in which you might want to use the COM+ object pooling service include the following:
When the costs of creating an object are relatively high. When usage costs are relatively low. When an object will be reused often. When you want to limit the number of object instances.
| | 9: | State a few guidelines for designing a queued component. | |
A9:
| While designing a queued component you must consider the following guidelines:
Methods should not return any value or reference parameters. All calls made by the client should be self-sufficient. The queued component has no way to generate a callback to the client program if more information is needed. Methods should not throw any application-specific exceptions because the client may not be available to respond to the exceptions.
| | 10: | What is a COM Callable Wrapper (CCW)? | |
A10:
| A CCW is a proxy object generated by the CLR so that existing COM applications can use .NET Framework components transparently. |
Exam Questions
| 1: | You create a COM+ application named "Inventory Application." This application contains a single serviced component named InventoryStatus that is present in an assembly named inventorystatus.dll. The InventoryStatus component is used by many client applications to monitor the status of the inventory. The client applications access the serviced component on a frequent basis. Which of the following options should you choose to ensure that the methods on InventoryStatus are processed as quickly as possible?
Configure Inventory Application to be a server application. Configure Inventory Application to be a library application. Configure the InventoryStatus component to use object pooling. Configure the InventoryStatus component to use just-in-time Activation.
| |
A1:
| B. Method calls execute fastest when the application is configured as a library application. The library application executes in the client's process. For more information, see the section "COM+ Applications" in this chapter. | | 2: | You are creating a serviced component that will be called from both managed and unmanaged client applications. You use a class library project to write the business logic and then compile the project into a strongly named assembly. As a next step, you want to register the assembly in the COM+ Catalog. You want to detect and correct any registration errors before any client applications use the component. Which of the following tools should you use to register the assembly?
Use the Assembly Registration tool (regasm.exe) to create entries in the Registry that describe the assembly. Use the Type Library Exporter (tlbexp.exe) to export the definition for the assembly. Use the Global Assembly Cache tool (gacutil.exe) to add the component to the global assembly cache. Use the .NET Services Installation tool (regsvcs.exe) to add the component to the COM+ Catalog.
| |
A2:
| D. Among the given options, the only tool that actually registers a strongly named assembly with the COM+ Catalog is the .NET Services Installation tool (regsvcs.exe). For more information, see the section "Registering the Serviced Component into the COM+ Catalog" in this chapter. | | 3: | You create a serviced component that allows users to connect to a homegrown ERP system that your company uses for various critical business operations. You register the component to the COM+ Catalog of the main application server. You enable the object pooling service for the component and set the Minimum Pool Size to 10 and Maximum Pool Size to 75. You monitor the statistics for the serviced component and find that 75 objects are already in use. What is the most likely result if one more request for an object is received?
The request is queued until either a connection is available or the timeout limit has been exceeded. The request for the object is well received and a new object is created. The request generates an exception. The serviced component uses just-in-time activation to deactivate the objects that are not in use and then create an object for the new request.
| |
A3:
| A. If no object is available and no new object can be created because of the size restriction of the pool, the client requests are queued to receive the first available object from the pool. If an object cannot be made available within the time specified in the CreationTimeOut property, an exception is thrown. For more information, see the section "How Object Pooling Works" in this chapter. | | 4: | You create a serviced component named OrderProcess. This component updates several SQL Server databases to complete a customer's order. The OrderProcess class includes the following code:
[Transaction(TransactionOption.Required)]
public class OrderProcess :
ServicedComponent
{
public void PlaceOrder(OrderInfo o)
{
// code to update various databases
}
}
You must ensure the reliability of the PlaceOrder() method. The PlaceOrder() method should update either all or none of the databases. What should you do?
Add the following attribute to the OrderProcess class:
[JustInTimeActivation(false)]
Add the following attribute to the PlaceOrder() method:
[AutoComplete()]
Add the following line of code at the end of the PlaceOrder() method:
ContextUtil.EnableCommit();
Add the following line of code at the end of the PlaceOrder() method:
ContextUtil.SetComplete();
| |
A4:
| B. When you use the AutoComplete attribute with a method, COM+ intercepts the method call to set the done bit and consistent bits after the method call returns. If there are no errors in the method call then the consistent bit is set to True; otherwise the consistent bit is set to False. This setting ensures that the changes to the database are committed or rolled backed reliably. For more information, see the section "How Automatic Transaction Works" in this chapter. | | 5: | You create a serviced component named OrderProcess. This component receives orders from the client applications in an asynchronous fashion. The OrderProcess class includes the following code:
namespace Exam70320
{
public interface IOrderProcess
{
void PlaceOrder(OrderInfo o);
}
[Transaction(TransactionOption.Required)]
[InterfaceQueuing(Enabled=true,
Interface="IOrdering")]
public class OrderProcess :
ServicedComponent,
IOrderProcess
{
public void PlaceOrder(OrderInfo o)
{
// code to update various databases
}
}
}
You need to write code for a client program that uses the OrderProcess component to place an order. Which code segment should you use?
IOrderProcess order = new IOrderProcess();
Order.PlaceOrder(orderInfo);
IOrderProcess order;
order = (IOrderProcess)
Activator.GetObject
(typeof(IOrderProcess),
@"queued:/new:Exam70320.OrderProcess");
order.PlaceOrder(orderInfo);
IOrderProcess order;
order = (IOrderProcess)
Marshal.BindToMoniker
(@"queue:/new:Exam70320.OrderProcess");
order.PlaceOrder(orderInfo);
IOrderProcess order;
order = (IOrderProcess)
Assembly.CreateInstance
(@"queue:/new:Exam70320.OrderProcess");
order.PlaceOrder(orderInfo);
| |
A5:
| C. You use the Marshal.BindToMoniker() method to record messages for a queued component. For more information, see the section "Creating a Client for a Queued Component" in this chapter. | | 6: | You create a queued component named OrderProcess. This component receives orders from the client applications in an asynchronous fashion. The OrderProcess class includes the following code:
namespace Exam70320
{
public interface IOrderProcess
{
bool PlaceOrder(OrderInfo o);
}
[Transaction(TransactionOption.Required)]
[InterfaceQueuing(Enabled=true,
Interface="IOrderProcess")]
public class OrderProcess :
ServicedComponent,
IOrderProcess
{
public bool PlaceOrder(OrderInfo o)
{
// code to update various databases
}
}
}
You get no compilation errors, but when you register this component using the .NET Services Installation Tool (regsvcs.exe), you get an error message: Queuing not supported on interface 'IOrderProcess'. What should you do to resolve this error?
Apply the following attribute on the class:
[ApplicationQueuing(
Enabled=true, QueueListenerEnabled=true)]
Apply the InterfaceQueuing attribute on the IOrderProcess interface rather than on the OrderProcess class. Change the interface definition as follows and then change OrderProcess to implement this interface.
public interface IOrderProcess
{
void PlaceOrder(OrderInfo o);
}
Apply the AutoComplete attribute on the OrderProcess class.
| |
A6:
| C. The interface that a queued component uses for queuing must have void methods having only pass-by-value parameters. Therefore, you need to change the return type of the PlaceOrder() method from bool to void. For more information, see the section "Creating a Queued Component" in this chapter. | | 7: | You are developing a serviced component that several client applications will use. Some client applications are COM based, whereas the other client applications run on the .NET Framework. In the future, you plan to release new versions of your serviced component but do not want to recompile the client applications. How should you design the interfaces for such a serviced component?
Define an interface and then use that interface to implement the serviced component. On the serviced component set the following attribute:
[ClassInterface(ClassInterfaceType.None)]
Set the following attribute on the serviced component:
[ClassInterface(
ClassInterfaceType.AutoDual)]
Define an interface and then use that interface to implement the serviced component. Set the following attribute on the serviced component:
[ClassInterface(
ClassInterfaceType.AutoDual)]
Set the following attribute on the serviced component:
[ClassInterface(
ClassInterfaceType.AutoDispatch)]
| |
A7:
| A. The ClassInterfaceType.None is the recommended setting for the ClassInterface attribute. The ClassInterfaceType.AutoDual causes versioning problems, and ClassInterfaceType.AutoDispatch supports only late binding and does not allow configuration of methods through the Component Services administrative tool. For more information, see the section "Creating Interfaces That Are Visible to COM/COM+" in this chapter. | | 8: | You are writing a serviced component that will be used by users over the network. The number of users simultaneously supported by the component depends on the license agreement. Which of the following attributes would you use to restrict the number of simultaneous connections to the serviced component?
The JustInTimeActivation attribute The Transaction attribute The ObjectConstruction attribute The ObjectPooling attribute
| |
A8:
| D. You can use the COM+ object pooling service to restrict the number of objects for a serviced component. Therefore, you use the ObjectPooling attribute. For more information, see the section "Object Pooling" in this chapter. | | 9: | Your colleague is testing a queued component that she just developed. She can configure the serviced component with the Component Services administrative tool, but the client application cannot find the component. Which of the following options should you suggest to your colleague to resolve this problem?
Use the Assembly Registration tool (regasm.exe) to install the component in Windows Registry. Use the Global Assembly Cache tool (gacutil.exe) to install the component in the global assembly cache. Copy the component to the directory of the client application. Copy the component to the Windows system directory.
| |
A9:
| B. A queued component is activated as a server application. To ensure that the client is able to locate the component, you must install the component in the GAC. For more information, see the section "Installing the Component in the Global Assembly Cache" in this chapter. | | 10: | You are creating a serviced component named DataConnector. After the component is deployed, the system administrators should be able to configure the component to connect to various data sources by specifying the connection string of the data source. The serviced component will be used by both COM and .NET applications. You want to retrieve the specified connection string in your component and change the behavior of the serviced component. Which of the following techniques should you use to achieve this?
Override the Activate() method. Override the Construct() method. Override the Deactivate() method. Specify a constructor for the serviced component that receives a connection string as its parameter.
| |
A10:
| B. You should override the Construct() method to receive the connection string specified by the administrator. For more information, see the section "Object Construction" in this chapter. | | 11: | You have created a business object in Visual C# .NET. You want the business object to be used by COM clients as well as .NET clients. You want to deploy the business object on the client computers in such a way that the client can take advantage of late binding as well as early binding with the interfaces exposed by the business object. Which of the following methods would you use to accomplish this?
Use Visual Studio .NET, open the project's property pages and change the Register for COM Interop option to true. Use the Assembly Registration tool (regasm.exe) with its /tlb option. Use the Type Library Exporter tool (tlbexp.exe) that ships as a part of the .NET Framework SDK. Use the ConvertAssemblyToTypeLib() method of the TypeLibConverter class in the System.Runtime.InteropServices namespace.
| |
A11:
| B. Regasm.exe, when used with the /tlb option, registers the assembly in the Registry (for late binding) and creates a CCW in a tlb file, which can be used by the client programs at the time of compilation (early binding). For more information, see the section "Exporting .NET Components Aas COM Type Libraries" in this chapter. | | 12: | You have written the following code for a serviced component:
namespace Exam70320
{
public interface IOrderProcess
{
bool PlaceOrder(OrderInfo o);
}
[JustInTimeActivation(true)]
[Transaction(
TransactionOption.Required)]
public class OrderProcess :
ServicedComponent,
IOrderProcess
{
public bool PlaceOrder(OrderInfo o)
{
// code to update various databases
}
}
}
In the PlaceOrder() method you decide whether all the databases have been updated correctly. If yes then you commit the transaction and deactivate the current OrderProcess object. Which of the following methods should you use in the PlaceOrder() method to accomplish this requirement?
DisableCommit() EnableCommit() SetAbort() SetComplete()
| |
A12:
| D. You should use the SetComplete() method because it sets the consistent bit as well as the done bit to true. Using the EnableCommit() method sets the consistent bit to true but also sets the done bit to false, which does not deactivate the object after the method call returns. For more information, see the section "Elements of Transaction Processing" in this chapter. | | 13: | You create a serviced component that will be used by only the .NET client programs. You want to use the COM+ object creation service from the serviced component. Which of the following steps must you take for the programs to use the serviced component? (Select all that apply.)
Register the component in the Windows Registry. Install the component in the global assembly cache. Sign the component with a strong name. Register the component in the COM+ Catalog.
| |
A13:
| C, D. You must at least sign the component with a strong name and then register the component in the COM+ Catalog. Just registering the component with the Windows Registry is not sufficient, because the component must be available to COM+. In addition, installing the component in the global assembly cache is not required as long as you make sure that the process can locate the assembly. For more information, see the section "Creating and Consuming a Serviced Component" in this chapter. | | 14: | You are developing a distributed order processing application for your company. The sales associates receive orders over the telephone. The orders are entered in the ordering system through a Windows form application. The Windows form application calls a set of serviced components to accomplish tasks. You must continue to receive orders even if one or more order processing components fail. Which of the following COM+ services should you use in the serviced components to ensure high availability of the system?
Queued components Automatic transactions Object pooling Just-in-time activation
| |
A14:
| A. To ensure high availability of the components, you should use the COM+ queued component service. For more information, see the section "Queued Components" in this chapter. | | 15: | You have been given an assignment to develop the order processing application for your organization. The application needs to support a large number of users and should perform well even between 8:00 a.m. and 12:00 noon, which is the peak time for receiving and processing orders. Which of the following COM+ services would you use in your application? (Select all that apply.)
Queued components Automatic transactions Object pooling Just-in-time activation
| |
A15:
| C, D. For achieving maximum performance, you can use COM+ object pooling and just-in-time activation services. For more information, see the section "Using Just-in-Time Activation with Object Pooling—A Recipe for High Throughput" in this chapter. |
Suggested Readings and Resources
1. Visual Studio .NET Combined Help Collection
• Writing Serviced Components
• Serviced Components Programming Guidelines
• COM+ Programming Overview
2. Building Distributed Applications with .NET, msdn.microsoft.com/nhp/default.asp?contentid=28001271.
3. The .NET Six-week series guide, msdn.microsoft.com/net/guide.
4. MSDN Index of How-To Articles, msdn.microsoft.com/howto/howto_index.asp.
5. .NET Architectural Sample Applications, msdn.microsoft.com/library/en-us/dnbda/html/bdadotnetsamp0.asp.
6. Enterprise Development Technology Map, msdn.microsoft.com/library/en-us/Dndotnet/html/Techmap_enterprise1.asp.
7. Derek Beyer. C# COM+ Programming. M&T Books, 2001.
8. Juval Lowy. COM and .NET Component Services. O'Reilly, 2001.
9. Roger Sessions. COM+ and the Battle for the Middle Tier. John Wiley & Sons, Inc. 2000.
|