private void OnDiagnosticsUpdated(object sender, DiagnosticsUpdatedArgs e) { AssertIfNull(e.GetAllDiagnosticsRegardlessOfPushPullSetting()); // all events are serialized by async event handler RaiseDiagnosticsUpdated((IDiagnosticUpdateSource)sender, e); }
private bool UpdateDataMap(IDiagnosticUpdateSource source, DiagnosticsUpdatedArgs args) { // we expect source who uses this ability to have small number of diagnostics. lock (_gate) { Debug.Assert(_updateSources.Contains(source)); // The diagnostic service itself caches all diagnostics produced by the IDiagnosticUpdateSource's. As // such, we want to grab all the diagnostics (regardless of push/pull setting) and cache inside // ourselves. Later, when anyone calls GetDiagnostics or GetDiagnosticBuckets we will check if their // push/pull request matches the current user setting and return these if appropriate. var diagnostics = args.GetAllDiagnosticsRegardlessOfPushPullSetting(); // check cheap early bail out if (diagnostics.Length == 0 && !_map.ContainsKey(source)) { // no new diagnostic, and we don't have update source for it. return(false); } // 2 different workspaces (ex, PreviewWorkspaces) can return same Args.Id, we need to // distinguish them. so we separate diagnostics per workspace map. var workspaceMap = _map.GetOrAdd(source, _ => new Dictionary <Workspace, Dictionary <object, Data> >()); if (diagnostics.Length == 0 && !workspaceMap.ContainsKey(args.Workspace)) { // no new diagnostic, and we don't have workspace for it. return(false); } var diagnosticDataMap = workspaceMap.GetOrAdd(args.Workspace, _ => new Dictionary <object, Data>()); diagnosticDataMap.Remove(args.Id); if (diagnosticDataMap.Count == 0 && diagnostics.Length == 0) { workspaceMap.Remove(args.Workspace); if (workspaceMap.Count == 0) { _map.Remove(source); } return(true); } if (diagnostics.Length > 0) { // save data only if there is a diagnostic var data = source.SupportGetDiagnostics ? new Data(args) : new Data(args, diagnostics); diagnosticDataMap.Add(args.Id, data); } return(true); } }
/// <summary> /// Gets all the diagnostics for this event, respecting the callers setting on if they're getting it for pull /// diagnostics or push diagnostics. Most clients should use this to ensure they see the proper set of /// diagnostics in their scenario (or an empty array if not in their scenario). /// </summary> public static ImmutableArray <DiagnosticData> GetPushDiagnostics( this DiagnosticsUpdatedArgs args, IGlobalOptionService globalOptions, Option2 <DiagnosticMode> diagnosticMode) { // If pull diagnostics are on, they get nothing since they're asking for push diagnostics. if (globalOptions.IsPullDiagnostics(diagnosticMode)) { return(ImmutableArray <DiagnosticData> .Empty); } return(args.GetAllDiagnosticsRegardlessOfPushPullSetting()); }