/// <summary> /// Initializes a new instance of the <see cref="ProfileOperation" /> class.<br /> /// This method indended to be called from <see cref="ProfileSession"/> /// and should not be called manually. /// </summary> public ProfileOperation(int id, [NotNull] ProfileSession session, [NotNull] ProfileOperationSpecification specification) : this(id : id, profiler : session.Profiler, session : session, specification : specification, parent : null) { }
/// <summary> /// Initializes a new instance of the <see cref="ProfileOperation" /> class.<br /> /// This method indended to be called from <see cref="ProfileSession"/> /// and should not be called manually. /// </summary> public ProfileOperation(int id, [NotNull] IProfiler profiler, [CanBeNull] ProfileSession session, [NotNull] ProfileOperationSpecification specification, [CanBeNull] ProfileOperation parent) { if (specification == null) { throw new ArgumentNullException(nameof(specification)); } this.Id = id; this.Profiler = profiler ?? throw new ArgumentNullException(nameof(profiler)); if (session != null) { if (session.Profiler != profiler) { throw new InvalidOperationException("Session.Profiler does not match specified profiler."); } this.Session = session; this.StartTime = session.Time; } if (this.Profiler.Configuration.CaptureCallStacks) { var current_assembly = this.GetType().Assembly; this.CallStack = new StackTrace(true).ToAsyncString(x => x.DeclaringType?.Assembly != current_assembly); } this.Name = specification.Name; this.Category = specification.Category; this.Resource = specification.Resource; this.NormalDuration = specification.NormalDuration; this.StartDate = DateTime.UtcNow; this.Parent = parent; if (specification.Data != null) { this.Data = new Dictionary <string, object>(specification.Data, StringComparer.Ordinal); } // start timer as close to the profiled code as possible this.time = Stopwatch.StartNew(); }