private void Run() { try { try { try { BeforeTask(); ThreadAbortException ex = threadAbortScope.Run(invoker.Invoke); if (ex != null) { NotifyTerminated(TaskResult <object> .CreateFromException(ex)); } else { NotifyTerminated(TaskResult <object> .CreateFromValue(invoker.Result)); } } finally { AfterTask(); } } catch (Exception ex) { NotifyTerminated(TaskResult <object> .CreateFromException(ex)); } } catch (Exception ex) { UnhandledExceptionPolicy.Report("An unhandled exception occurred in a thread task.", ex); } }
private void HandleProcessExit() { // The process lock may already be held by this thread since the // Process object can call its Exited event handler as a side effect of // several operations on the Process object. This could result in a // deadlock if the task's Terminated event waits on some other thread that // is also blocked on the process. So we make it asynchronous instead. // Join then blocks on the exitedEvent to restore the required synchronization. if (Interlocked.Exchange(ref exited, 1) == 0) { ThreadPool.QueueUserWorkItem((state) => { try { WaitForConsoleToBeCompletelyReadOnceProcessHasExited(); NotifyTerminated(TaskResult <object> .CreateFromValue(ExitCode)); } finally { exitedEvent.Set(); } }, null); } }