// Thread routine for the poll loop. It handles calls coming in from the debug engine as well as polling for debug events. private void ThreadFunc() { while (!_isClosed) { // Wait for an operation to be set _opSet.WaitOne(); // Run until we go through a loop where there was nothing to do bool ranOperation; do { ranOperation = false; OperationDescriptor runningOp = _runningOp; if (runningOp != null && !runningOp.IsStarted) { runningOp.MarkStarted(); ranOperation = true; bool completeAsync = false; Operation syncOp = runningOp.Target as Operation; if (syncOp != null) { try { syncOp(); } catch (Exception opException) when(ExceptionHelper.BeforeCatch(opException, Logger, reportOnlyCorrupting: true)) { runningOp.ExceptionDispatchInfo = ExceptionDispatchInfo.Capture(opException); } } else { AsyncOperation asyncOp = (AsyncOperation)runningOp.Target; try { runningOp.Task = asyncOp(); } catch (Exception opException) when(ExceptionHelper.BeforeCatch(opException, Logger, reportOnlyCorrupting: true)) { runningOp.ExceptionDispatchInfo = ExceptionDispatchInfo.Capture(opException); } if (runningOp.Task != null) { runningOp.Task.ContinueWith(OnAsyncRunningOpComplete, TaskContinuationOptions.ExecuteSynchronously); completeAsync = true; } } if (!completeAsync) { runningOp.MarkComplete(); Debug.Assert(_runningOp == runningOp, "How did m_runningOp change?"); _runningOp = null; _runningOpCompleteEvent.Set(); } } Operation postedOperation = null; lock (_postedOperations) { if (_postedOperations.Count > 0) { postedOperation = _postedOperations.Dequeue(); } } if (postedOperation != null) { ranOperation = true; try { postedOperation(); } catch (Exception e) when(ExceptionHelper.BeforeCatch(e, Logger, reportOnlyCorrupting: false)) { if (PostedOperationErrorEvent != null) { PostedOperationErrorEvent(this, e); } } } }while (ranOperation); } }