private void Worker(object threadStarted) { try { SynchronizationContext.SetSynchronizationContext(new AnalysisSynchronizationContext(this)); } finally { ((AutoResetEvent)threadStarted).Set(); } AnalysisStarted?.Invoke(this, EventArgs.Empty); _isAnalyzing = true; CancellationToken cancel; try { cancel = _cancel.Token; } catch (ObjectDisposedException) { AnalysisAborted?.Invoke(this, EventArgs.Empty); return; } while (!cancel.IsCancellationRequested) { IAnalyzable workItem; AnalysisPriority pri; lock (_queueLock) { workItem = GetNextItem(out pri); } if (workItem != null) { try { var groupable = workItem as IGroupableAnalysisProjectEntry; if (groupable != null) { var added = _enqueuedGroups.Add(groupable.AnalysisGroup); if (added) { Enqueue(new GroupAnalysis(groupable.AnalysisGroup, this), pri); } groupable.Analyze(cancel, true); } else { workItem.Analyze(cancel); } } catch (Exception ex) when(!ex.IsCriticalException() && !Debugger.IsAttached) { UnhandledException?.Invoke(this, new UnhandledExceptionEventArgs(ex, false)); _cancel.Cancel(); } } else if (!_workEvent.WaitOne(50)) { // Short wait for activity before raising the event. _isAnalyzing = false; var evt1 = AnalysisComplete; if (evt1 != null) { ThreadPool.QueueUserWorkItem(_ => evt1(this, EventArgs.Empty)); } try { _workEvent.WaitOne(); } catch (ApplicationException) { // No idea where this is coming from... try { _cancel.Cancel(); } catch (ObjectDisposedException) { // Doesn't matter - we're breaking out anyway } break; } var evt2 = AnalysisStarted; if (evt2 != null) { ThreadPool.QueueUserWorkItem(_ => evt2(this, EventArgs.Empty)); } _isAnalyzing = true; } } _isAnalyzing = false; if (cancel.IsCancellationRequested) { AnalysisAborted?.Invoke(this, EventArgs.Empty); } }
private void Worker(object threadStarted) { try { SynchronizationContext.SetSynchronizationContext(new AnalysisSynchronizationContext(this)); _scheduler = TaskScheduler.FromCurrentSynchronizationContext(); } finally { ((AutoResetEvent)threadStarted).Set(); } AnalysisStarted?.Invoke(this, EventArgs.Empty); _isAnalyzing = true; while (!_cancel.IsCancellationRequested) { IAnalyzable workItem; AnalysisPriority pri; lock (_queueLock) { workItem = GetNextItem(out pri); } if (workItem != null) { try { var groupable = workItem as IGroupableAnalysisProjectEntry; if (groupable != null) { bool added = _enqueuedGroups.Add(groupable.AnalysisGroup); if (added) { Enqueue(new GroupAnalysis(groupable.AnalysisGroup, this), pri); } groupable.Analyze(_cancel.Token, true); } else { workItem.Analyze(_cancel.Token); } } catch (Exception ex) { if (ex.IsCriticalException() || System.Diagnostics.Debugger.IsAttached) { throw; } _analyzer.ReportUnhandledException(ex); _cancel.Cancel(); } } else if (!_workEvent.WaitOne(50)) { // Short wait for activity before raising the event. _isAnalyzing = false; var evt1 = AnalysisComplete; if (evt1 != null) { ThreadPool.QueueUserWorkItem(_ => evt1(this, EventArgs.Empty)); } WaitHandle.SignalAndWait(_analyzer.QueueActivityEvent, _workEvent); var evt2 = AnalysisStarted; if (evt2 != null) { ThreadPool.QueueUserWorkItem(_ => evt2(this, EventArgs.Empty)); } _isAnalyzing = true; } } _isAnalyzing = false; if (_cancel.IsCancellationRequested) { AnalysisAborted?.Invoke(this, EventArgs.Empty); } }