Rafael Zuniga, Stephen Cave
Summary:
The purpose of this lab is to create an asynchronous client proxy that will issue concurrent requests to a singleton service.
Procedure:
We begin by opening the solution in the Chapter5/Concurrency found in the labs directory. A service has already been made which allows clients to add words to a dictionary. The service runs as a single instance using ConcurrencyMode set to Single as well. In order for our client to be able to use the service we must generate a proxy by running:
svcutil /a /o:proxy.cs /config:app.config http://localhost:8000
This will generate a client proxy to be used by our client application. Next we must edit the client to actually use the service. The client already includes the three buttons to call the service but we must implement the actual event handlers by adding the following:
MessagingServiceClient proxy = new MessagingServiceClient();
And filling in the event handlers for each of the three buttons. We also modify the close event to close the client proxy. Building the solution and running it we see the following when the client buttons are used:

Next we modify the concurrency mode to multiple and test again. This time instead of seeing the ordered service call we see multiple exceptions:

In order to prevent multiple service calls from attempting to access the same variable at once we must synchronize access. The MessagingService.cs is modified to include locking mechanisms. First we modify SendMessage1 by adding a try/finally statement in which a Monitor is used to lock the current service object. The SendMessage2 function is synchronized in a different way; instead of using a monitor we use the lock statement to gain a lock on the service object. The final function, SendMessage3, is synchronized using an attribute:
[MethodImpl(MethodImplOptions.Synchronized)]
The project is then recompiled and tested again. This time the results are the same as the first screen shot, that is, no exceptions are thrown and we see each of the calls. Since the currently example locks the whole service object it isn't very efficient if there are multiple resources that require access. Instead of locking the whole object, this time we modify the existing code to use a mutex. A new dictionary variable is added along with a mutex for each of the variables. The first two SendMessage funtions are modified to the first mutex in order to access the first dictionary and the third SendMessage function is modified to lock the second mutex when accessing the second dictionary. Rebuilding and running it gives us the same effect as in the first screen shot, that is, there are no exceptions thrown.
Observations:
- There are many ways to lock a resource: mutexes, monitors, the lock keyword, etc
- If there's more than one resource it's more efficient to lock it singly instead of locking the whole service object which prevents other clients from accessing other services
- If I remember correctly another way to lock a section of code is to use the lock keyword but on a lock dummy object which should only block access to that object and not the whole service
- Blogger has problems with some C# code so a lot of it has been omitted
- I bet it's those angle bracket things
No comments:
Post a Comment