private static ImmutableArray <IExporter> GetExporters(IEnumerable <IExporter> exporters, ImmutableHashSet <IDiagnoser> uniqueDiagnosers) { var result = new List <IExporter>(); foreach (var exporter in exporters) { if (!result.Contains(exporter)) { result.Add(exporter); } } foreach (var diagnoser in uniqueDiagnosers) { foreach (var exporter in diagnoser.Exporters) { if (!result.Contains(exporter)) { result.Add(exporter); } } } var hardwareCounterDiagnoser = uniqueDiagnosers.OfType <IHardwareCountersDiagnoser>().SingleOrDefault(); var disassemblyDiagnoser = uniqueDiagnosers.OfType <IDisassemblyDiagnoser>().SingleOrDefault(); // we can use InstructionPointerExporter only when we have both IHardwareCountersDiagnoser and IDisassemblyDiagnoser if (hardwareCounterDiagnoser != default(IHardwareCountersDiagnoser) && disassemblyDiagnoser != default(IDisassemblyDiagnoser)) { result.Add(new InstructionPointerExporter(hardwareCounterDiagnoser, disassemblyDiagnoser)); } for (int i = result.Count - 1; i >= 0; i--) { if (result[i] is IExporterDependencies exporterDependencies) { foreach (var dependency in exporterDependencies.Dependencies) { if (!result.Contains(dependency)) { result.Insert(i, dependency); // All the exporter dependencies should be added before the exporter } } } } result.Sort((left, right) => (left is IExporterDependencies).CompareTo(right is IExporterDependencies)); // the case when they were defined by user in wrong order ;) return(result.ToImmutableArray()); }
/// <inheritdoc/> public override void Dispose() { foreach (IDisposable transmitter in _transmitters.OfType <IDisposable>()) { transmitter.Dispose(); } base.Dispose(); }
public bool HasMemoryDiagnoser() => diagnosers.OfType <MemoryDiagnoser>().Any();
private static ImmutableArray <IExporter> GetExporters(IEnumerable <IExporter> exporters, ImmutableHashSet <IDiagnoser> uniqueDiagnosers, IList <Conclusion> configAnalyse) { void AddWarning(string message) { var conclusion = Conclusion.CreateWarning("Configuration", message); configAnalyse.Add(conclusion); } var mergeDictionary = new Dictionary <System.Type, IExporter>(); foreach (var exporter in exporters) { var exporterType = exporter.GetType(); if (mergeDictionary.ContainsKey(exporterType)) { AddWarning($"The exporter {exporterType} is already present in configuration. There may be unexpected results."); } mergeDictionary[exporterType] = exporter; } foreach (var diagnoser in uniqueDiagnosers) { foreach (var exporter in diagnoser.Exporters) { var exporterType = exporter.GetType(); if (mergeDictionary.ContainsKey(exporterType)) { AddWarning($"The exporter {exporterType} of {diagnoser.GetType().Name} is already present in configuration. There may be unexpected results."); } mergeDictionary[exporterType] = exporter; } } ; var result = mergeDictionary.Values.ToList(); var hardwareCounterDiagnoser = uniqueDiagnosers.OfType <IHardwareCountersDiagnoser>().SingleOrDefault(); var disassemblyDiagnoser = uniqueDiagnosers.OfType <DisassemblyDiagnoser>().SingleOrDefault(); // we can use InstructionPointerExporter only when we have both IHardwareCountersDiagnoser and DisassemblyDiagnoser if (hardwareCounterDiagnoser != default(IHardwareCountersDiagnoser) && disassemblyDiagnoser != default(DisassemblyDiagnoser)) { result.Add(new InstructionPointerExporter(hardwareCounterDiagnoser, disassemblyDiagnoser)); } for (int i = result.Count - 1; i >= 0; i--) { if (result[i] is IExporterDependencies exporterDependencies) { foreach (var dependency in exporterDependencies.Dependencies) { /* * When exporter that depends on an other already present in the configuration print warning. * * Example: * * // Global Current Culture separator is Semicolon; * [CsvMeasurementsExporter(CsvSeparator.Comma)] // force use Comma * [RPlotExporter] * public class MyBanch * { * * } * * RPlotExporter is depend from CsvMeasurementsExporter.Default * * On active logger will by print: * "The CsvMeasurementsExporter is already present in the configuration. There may be unexpected results of RPlotExporter. * */ if (!result.Any(exporter => exporter.GetType() == dependency.GetType())) { result.Insert(i, dependency); // All the exporter dependencies should be added before the exporter } else { AddWarning($"The {dependency.Name} is already present in the configuration. There may be unexpected results of {result[i].GetType().Name}."); } } } } result.Sort((left, right) => (left is IExporterDependencies).CompareTo(right is IExporterDependencies)); // the case when they were defined by user in wrong order ;) return(result.ToImmutableArray()); }