Encapsulating Threads

I l @ ve RuBoard

To get a better handle on creating, managing, and working with threads, a good strategy is to use encapsulation. Creating a class to encapsulate your threads is not the only answer to the control problem, but it is the cleanest. Being able to handle your threads in an object-oriented manner not only simplifies the management of those threads but prevents misuse by other developers. Remember one of the central themes of this book: always explicitly design your code for how it should be used!

Note

Encapsulating your threads also allows you to implement both synchronous and asynchronous interfaces for greater flexibility, depending on your application's needs. We'll investigate this further in following sections.


Wrapping a Thread with a Class

In the earlier section titled "An Overview of Basic Threading Concepts," all the work to create the threads had to be done, repeatedly, by the main subroutine. From a development standpoint, this is not particularly efficient and can lead to programming errors. (Repetition is rarely desirable.) The solution is to encapsulate the thread's implementation and runtime logic into a separate class, as in the following example:

 ImportsSystem.Threading PublicClassMyThreadClass Privatem_ThreadAsThread PublicSubNew() Me.m_Thread=NewThread(AddressOfMe.Run) EndSub PublicSubStart() Me.m_Thread.Start() EndSub PrivateSubRun() 'Thethread'smainlogicgoeshere. EndSub EndClass 

This is a good start, but it suffers from a major limitation. We cannot set initial conditions for this thread. We need to find a way to give the Run method some information to differentiate one MyThreadClass from another. We can do this most simply by providing a parameterized constructor. This makes the class inherently more useful by allowing it to perform different tasks based on different initial conditions. Using the class-based encapsulation scheme, you can pass parameters to the thread through the class's constructor. The constructor will then set some private variables that the thread can access when it needs to.

Warning

You can also use public properties on the class to set or modify the thread conditions, but I won't address how to do this safely until we get to the "Thread Synchronization" section later in the chapter. For the time being, the safest way to implement this is to set the properties before the thread starts. The constructor is the perfect place to do this in an enforceable manner.


If we extend the class we just created to function like the Basic Threading example, we end up with a class that looks something like the following:

 ImportsSystem.Threading PublicClassMyThreadClass Privatem_ThreadAsThread Privatem_IdAsInteger Privatem_LoopCountAsInteger PublicSubNew(ByValidAsInteger,ByValloopCountAsInteger) Me.m_Id=id Me.m_LoopCount=loopCount Me.m_Thread=NewThread(AddressOfMe.Run) EndSub PublicSubStart() Me.m_Thread.Start() EndSub 'Thisisaninstancemethod. 'Notethatitcanusethe'Me'referencepointer. PrivateSubRun() DimiAsInteger Fori=0ToMe.m_LoopCount Console.WriteLine("Thread{0}{1}",Me.m_Id,i) Next EndSub EndClass 

Now we have a class that can provide information to a thread so it can identify itself, and we can customize its behavior. As a result, we can create several different instances of MyThreadClass , all of which will behave according to the supplied initial conditions. We also have made it simple to create new threads, and we've built the requirements for encapsulation into the design itself. With this implementation, it is impossible to create an instance of My ­ThreadClass without supplying the required initial conditions. This allows us to avoid putting in error-handling code or default settings. Take a look at how much simpler the implementation code looks:

 ModuleModule1 SubMain() Dimt1AsNewMyThreadClass(1,200) Dimt2AsNewMyThreadClass(2,300) t1.Start() t2.Start() 'Again,wewaitforthethreadstofinish. Console.ReadLine() EndSub EndModule 

Now you see how you can encapsulate threads to simplify implementation and provide better control over how information is passed to the threads. Also note that you can use this mechanism to return information that results from thread execution. This all leads into the discussion of how to control the execution of your threads.

I l @ ve RuBoard


Designing Enterprise Applications with Microsoft Visual Basic .NET
Designing Enterprise Applications with Microsoft Visual Basic .NET (Pro-Developer)
ISBN: 073561721X
EAN: 2147483647
Year: 2002
Pages: 103

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