private async Task Initialize() { await this.semaphoreSlim.WaitAsync(); try { if (this.initialized == 1) { return; } var filterParams = new FilterParams { StartTimeRelativeMSec = this.model.Start, EndTimeRelativeMSec = this.model.End, ExcludeRegExs = this.model.ExcPats, IncludeRegExs = this.model.IncPats, FoldRegExs = this.model.FoldPats, GroupRegExs = this.model.GroupPats, MinInclusiveTimePercent = this.model.FoldPct, Name = "NoName", }; var ss = new FilterStackSource(filterParams, this.stackSource, ScalingPolicyKind.TimeMetric); double startTimeRelativeMsec = double.TryParse(filterParams.StartTimeRelativeMSec, out startTimeRelativeMsec) ? Math.Max(startTimeRelativeMsec, 0.0) : 0.0; double endTimeRelativeMsec = double.TryParse(filterParams.EndTimeRelativeMSec, out endTimeRelativeMsec) ? Math.Min(endTimeRelativeMsec, this.stackSource.SampleTimeRelativeMSecLimit) : this.stackSource.SampleTimeRelativeMSecLimit; var c = new CallTree(ScalingPolicyKind.TimeMetric); c.TimeHistogramController = new TimeHistogramController(c, startTimeRelativeMsec, endTimeRelativeMsec); c.StackSource = ss; if (float.TryParse(filterParams.MinInclusiveTimePercent, out float minIncusiveTimePercent) && minIncusiveTimePercent > 0) { c.FoldNodesUnder(minIncusiveTimePercent * c.Root.InclusiveMetric / 100, true); } var t = new Tuple(c); this.tuple = t; this.initialized = 1; } finally { this.semaphoreSlim.Release(); } }