Context

Team-Fly    

 
Application Development Using Visual Basic and .NET
By Robert J. Oberg, Peter Thorsteinson, Dana L. Wyatt
Table of Contents
Chapter 10.  .NET Framework Classes


In order for us to understand how the runtime is able to enforce a threading requirement based on an attribute, we have to introduce the concept of context. Step 4 of the Threading example is the same code as Step 3, but with some additional output:

 graphics/codeexample.gif Is the customer object a proxy? False Is the bookings object a proxy? True Added Boston Presidential Hotel with one room. Thread 111 ContextId 0 launching 3 threads. MakeReservation: Thread 126 ContextId 0 starting. MakeReservation: Thread 127 ContextId 0 starting. CancelReservation: Thread 128 ContextId 0 starting. Cancelling Reservation 10 Thread 128 ContextId 1 entered CancelReservation. Thread 128 ContextId 1 left CancelReservation. Reserving for Customer 2 ... on 12/13/2001 ... for 1 days Reserving for Customer 1 ... on 12/12/2001 ... for 3 days Thread 127 ContextId 1 entered Reserve. Thread 127 sleeping in Broker::Reserve Thread 127 ContextId 1 left Reserve. Thread 126 ContextId 1 entered Reserve. Thread 126 ContextId 1 left Reserve. Reservation for Customer 1 could not be booked Room not available Reservation for Customer 2 has been booked ReservationId = 1 ReservationRate = 10000 ReservationCost = 10000 Comment = OK Done! 

In this last step of the Threading example, we see that when a thread enters a method of the Broker class, it has a different ContextId than when it runs outside of the Broker class. It runs in a different context.

 MakeReservation: Thread 127 ContextId 0 starting. ... Thread 127 ContextId 1 entered Reserve. 

Broker objects have different runtime requirements than the other objects in the program, since access to Broker objects must be synchronized and access to other objects should not be synchronized. The environment that represents the runtime requirements of an object is called a context . There are two contexts in the Threading Step 3 example: Context 1 where the Broker object lives and Context 0 where all other objects live. Every thread in the program runs in Context 1 when executing inside a Broker object and in Context 0 everywhere else. Contexts are independent of threads.

A context is a collection of one or more objects that have identical run-time requirements. The .NET concept of a context is very similar to a COM apartment or to the COM+ concept of a context. [8] In general, you cannot say what the runtime must do in a given context because it depends on exactly what the runtime requirements are. A context that has transactional requirements requires different action than one that does not. A context that has to maintain a REQUIRED synchronization requirement is different than one that has to maintain a REQUIRES_NEW synchronization requirement.

[8] However, at this point in time COM+ contexts and .NET contexts are different. For a discussion of contexts in COM+, see Understanding and Programming COM+ by Robert J. Oberg.

You can get the Context class instance that represents the current context from the shared property Thread.CurrentContext . ContextId is a property of that class.

Proxies and Stubs

How does the runtime enforce the different requirements of different contexts? When an object resides in another context (such as the HotelBroker object in the NewReservation instance), a reference to a proxy object is returned instead of a reference to the object itself. The actual object resides in its original, or home, context. The proxy is an object that represents the original object in a different context. The shared method RemotingServices.IsTransparentProxy determines if an object reference points to a real object instance or to a proxy. Look at the code in the Threading Step 4 example main routine:

 hotelBroker = New HotelBroker() customers = New Customers() Dim bTrans As Boolean bTrans = RemotingServices.IsTransparentProxy(customers) Console.WriteLine(_  "Is the customer object a proxy? {0}", bTrans) bTrans = RemotingServices.IsTransparentProxy(hotelBroker) Console.WriteLine(_  "Is the bookings object a proxy? {0}", bTrans) 

Which causes the following output:

 Is the customer object a proxy? False Is the bookings object a proxy? True 

When a program starts up, it is given a default context. [9] All objects, like the Customers object, that do not have any special requirements are created inside of that context (context 0). An object, such as the HotelBroker object, that has a different set of requirements (synchronization) is created in a different context (context 1), and a proxy is returned to the creating context (context 0).

[9] As will be clear in the next section, the sentence should really read, "When a new application domain starts up, it is given a new default context." Contexts are application domain-relative. Two different application domains will have two separate default contexts, each with id 0.

Now, when you access the MakeReservation method in the HotelBroker object, you are actually accessing a method on the proxy. The proxy method can then apply the synchronization lock and then delegate to the actual HotelBroker object's method. When the actual object's method returns, it returns to the proxy. The proxy can then remove the synchronization lock and return to the caller. This technique, where the runtime uses a proxy to intercept method calls to the actual object, is called interception .

ContextBoundObject

The Broker class has to derive from the class ContextBoundObject so that the runtime knows to set up a different context if one is required. If you remove the derivation of Broker from ContextBoundObject , you will once again get the threading conflict, and both customers will be able to reserve the last room at the hotel, even though the class is still marked with the Synchronization attribute. Objects that do not derive from ContextBoundObject can run in any context (agile objects).

Since other contexts work with a proxy or a reference to the actual object, the runtime must translate (marshal) the call from one context to another. Hence, ContextBoundObject inherits from MarshalByRefObject . MarshalByRefObject is the base class for objects that want to be able to be marshaled by reference.

One advantage of using synchronization techniques such as a Monitor is that a Monitor can be called from any context. Another potential disadvantage of using automatic synchronization is the performance hit from marshaling and using proxies rather than the actual object.

As will be clear when we discuss application domains, since the customer object has no dependency on context, it is the actual object, not a proxy. It can be copied to any context within the same application domain.


Team-Fly    
Top
 


Application Development Using Visual BasicR and .NET
Application Development Using Visual BasicR and .NET
ISBN: N/A
EAN: N/A
Year: 2002
Pages: 190

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net