protected void Teardown() { // Only dispose the dispatcher if it was created here. if (_hasLocalDispatcher) { // We are here because the FinalNode's ExitBehavior is running on the Dispatcher. // Attempting to dispose of the Dispatcher from the final executable using the Dispatcher's // own thread will cause the Dispatcher to kill (abort) it's thread. // That thread abort can be avoided by giving the Dispatcher cleanup to a different thread, // which allows the currently executing ExitBehavior to finish cleanly first. Task.Factory.StartNew(() => { LogService.Log(LogType, LogMessageType.Debug, GetType().Name, "Waiting for local dispatcher '" + Name + "' to be empty."); _dispatcher.WaitUntilDone(); LogService.Log(LogType, LogMessageType.Debug, GetType().Name, "'" + Name + "' is disposing."); // We are now completely done with the dispatcher. _dispatcher.Dispose(); _dispatcher = null; }); } try { _finishedEvent.Dispose(); } catch (ObjectDisposedException) { // reset event was disposed } //Dispose the UML nodes DisposeNodes(InitialNode); if (FinalNode != null) { // THIS MAY BE A PROBLEM if SimpleDispatcher is made to dispose IExecutables after executing them. FinalNode.Dispose(); } Dispose(); }