Active Objects


Object diagrams are also useful in multithreaded systems. Consider, for example, the SocketServer code in Listing 16-1. This program implements a simple framework that allows you to write socket servers without having to deal with all the nasty threading and synchronization issues that accompany sockets.

Listing 16-1. SocketServer.cs

using System.Collections; using System.Net; using System.Net.Sockets; using System.Threading; namespace SocketServer {   public interface SocketService   {     void Serve(Socket s);   }   public class SocketServer   {     private TcpListener serverSocket = null;     private Thread serverThread = null;     private bool running = false;     private SocketService itsService = null;     private ArrayList threads = new ArrayList();     public SocketServer(int port, SocketService service)     {       itsService = service;       IPAddress addr = IPAddress.Parse("127.0.0.1");       serverSocket = new TcpListener(addr, port);       serverSocket.Start();       serverThread = new Thread(new ThreadStart(Server));       serverThread.Start();     }     public void Close()     {       running = false;       serverThread.Interrupt();       serverSocket.Stop();       serverThread.Join();       WaitForServiceThreads();     }     private void Server()     {       running = true;       while (running)       {         Socket s = serverSocket.AcceptSocket();         StartServiceThread(s);       }     }     private void StartServiceThread(Socket s)     {       Thread serviceThread =         new Thread(new ServiceRunner(s, this).ThreadStart());       lock (threads)       {         threads.Add(serviceThread);       }       serviceThread.Start();     }     private void WaitForServiceThreads()     {       while (threads.Count > 0)       {         Thread t;         lock (threads)         {           t = (Thread) threads[0];         }         t.Join();       }     }     internal class ServiceRunner     {       private Socket itsSocket;       private SocketServer itsServer;       public ServiceRunner(Socket s, SocketServer server)       {         itsSocket = s;         itsServer = server;       }       public void Run()       {         itsServer.itsService.Serve(itsSocket);         lock (itsServer.threads)         {           itsServer.threads.Remove(Thread.CurrentThread);         }         itsSocket.Close();       }       public ThreadStart ThreadStart()       {         return new ThreadStart(Run);       }     }   } }

The class diagram for this code is shown in Figure 16-3. It's not very inspiring, and it's difficult to see what the intent of this code is from the class diagram. The figure shows all the classes and relationships, but somehow the big picture doesn't come through.

Figure 16-3. SocketServer class diagram


However, look at the object diagram in Figure 16-4. This shows the structure much better than the class diagram does. Figure 16-4 shows that the SocketServer holds onto the serverThread and that the serverThread runs in a delegate named Server(). It shows that the serverThread is responsible for creating all the ServiceRunner instances.

Figure 16-4. SocketServer object diagram


Note the heavy bold lines around the THRead instances. Objects with heavy bold borders represent active objects, which act as the head of a thread of control. They contain the methods, such as Start, Abort, Sleep, and so on, that control the thread. In this diagram, all the active objects are instances of Thread because all the processing is done in delegates that the Thread instances hold references to.

The object diagram is more expressive than the class diagram because the structure of this particular application is built at runtime. In this case, the structure is more about objects than about classes.




Agile Principles, Patterns, and Practices in C#
Agile Principles, Patterns, and Practices in C#
ISBN: 0131857258
EAN: 2147483647
Year: 2006
Pages: 272

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