WorkShift
The dispatcher needs to do different things at different,
             non-overlapped times. For example, non-parallel tests may
             not be run at the same time as parallel tests. We model
             this using the metaphor of a working shift. The WorkShift
             class associates one or more WorkItemQueues with one or
             more TestWorkers.
            
             Work in the queues is processed until all queues are empty
             and all workers are idle. Both tests are needed because a
             worker that is busy may end up adding more work to one of
             the queues. At that point, the shift is over and another
             shift may begin. This cycle continues until all the tests
             have been run.
             
                
Gets a bool indicating whether this shift has any work to do
            
Gets a flag indicating whether the shift is currently active
            
The Name of this shift
            
Event that fires when the shift has ended
            
Construct a WorkShift
            
Add a WorkItemQueue to the shift, starting it if the
            shift is currently active.
            
Assign a worker to the shift.
            
Cancel (abort or stop) the shift without completing all work
            
End the shift, pausing all queues and raising
            the EndOfShift event.
            
Shut down the shift.
            
Start or restart processing for the shift