1 // ***********************************************************************
2 // Copyright (c) 2014 Charlie Poole
4 // Permission is hereby granted, free of charge, to any person obtaining
5 // a copy of this software and associated documentation files (the
6 // "Software"), to deal in the Software without restriction, including
7 // without limitation the rights to use, copy, modify, merge, publish,
8 // distribute, sublicense, and/or sell copies of the Software, and to
9 // permit persons to whom the Software is furnished to do so, subject to
10 // the following conditions:
12 // The above copyright notice and this permission notice shall be
13 // included in all copies or substantial portions of the Software.
15 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
19 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
20 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22 // ***********************************************************************
25 #define NUNIT_FRAMEWORK
29 using System.Collections.Generic;
30 using System.Diagnostics;
31 using System.Threading;
33 namespace NUnit.Framework.Internal.Execution
36 /// SimpleWorkItemDispatcher handles execution of WorkItems by
37 /// directly executing them. It is provided so that a dispatcher
38 /// is always available in the context, thereby simplifying the
39 /// code needed to run child tests.
41 public class SimpleWorkItemDispatcher : IWorkItemDispatcher
44 // The first WorkItem to be dispatched, assumed to be top-level item
45 private WorkItem _topLevelWorkItem;
47 // Thread used to run and cancel tests
48 private Thread _runnerThread;
51 #region IWorkItemDispatcher Members
54 /// Dispatch a single work item for execution. The first
55 /// work item dispatched is saved as the top-level
56 /// work item and a thread is created on which to
57 /// run it. Subsequent calls come from the top level
58 /// item or its descendants on the proper thread.
60 /// <param name="work">The item to dispatch</param>
61 public void Dispatch(WorkItem work)
67 if (_topLevelWorkItem != null)
71 _topLevelWorkItem = work;
72 _runnerThread = new Thread(RunnerThreadProc);
74 #if !NETCF && !SILVERLIGHT
75 if (work.TargetApartment == ApartmentState.STA)
76 _runnerThread.SetApartmentState(ApartmentState.STA);
79 _runnerThread.Start();
85 private void RunnerThreadProc()
87 _topLevelWorkItem.Execute();
92 private object cancelLock = new object();
96 /// Cancel (abort or stop) the ongoing run.
97 /// If no run is in process, the call has no effect.
99 /// <param name="force">true if the run should be aborted, false if it should allow its currently running test to complete</param>
100 public void CancelRun(bool force)
105 if (_topLevelWorkItem != null)
107 _topLevelWorkItem.Cancel(force);
109 _topLevelWorkItem = null;