public static void ParseSnapshot( ListViewEx ExclusiveListView, List<FCallStackAllocationInfo> CallStackList, bool bShouldSortBySize, string FilterText ) { const int MaximumEntries = 400; // Progress bar. long ProgressInterval = MaximumEntries / 20; long NextProgressUpdate = ProgressInterval; int CallStackCurrent = 0; OwnerWindow.ToolStripProgressBar.Value = 0; OwnerWindow.ToolStripProgressBar.Visible = true; OwnerWindow.UpdateStatus("Updating exclusive list view for " + OwnerWindow.CurrentFilename); ExclusiveListView.BeginUpdate(); ExclusiveListView.ListViewItemSorter = null; // clear this to avoid a Sort for each call to Add // Sort based on passed in metric. if( bShouldSortBySize ) { CallStackList.Sort( CompareAbsSize ); } else { CallStackList.Sort( CompareCount ); } bool bFilterIn = OwnerWindow.IsFilteringIn(); using( FScopedLogTimer ParseTiming = new FScopedLogTimer( "FExclusiveListViewParser.ParseSnapshot" ) ) { // Figure out total size and count for percentages. long TotalSize = 0; long TotalCount = 0; foreach( FCallStackAllocationInfo AllocationInfo in CallStackList ) { // Apply optional filter. if( FStreamInfo.GlobalInstance.CallStackArray[ AllocationInfo.CallStackIndex ].RunFilters( FilterText, OwnerWindow.Options.ClassGroups, bFilterIn, OwnerWindow.SelectedMemoryPool ) ) { TotalSize += AllocationInfo.Size; TotalCount += AllocationInfo.Count; } } // Clear out existing entries and add top 400. ExclusiveListView.Items.Clear(); for( int CallStackIndex = 0; CallStackIndex < CallStackList.Count && ExclusiveListView.Items.Count <= MaximumEntries; CallStackIndex++ ) { // Update progress bar. if( CallStackCurrent >= NextProgressUpdate ) { OwnerWindow.ToolStripProgressBar.PerformStep(); NextProgressUpdate += ProgressInterval; Debug.WriteLine( "FExclusiveListViewParser.ParseSnapshot " + OwnerWindow.ToolStripProgressBar.Value + "/20" ); } CallStackCurrent++; FCallStackAllocationInfo AllocationInfo = CallStackList[ CallStackIndex ]; // Apply optional filter. FCallStack CallStack = FStreamInfo.GlobalInstance.CallStackArray[ AllocationInfo.CallStackIndex ]; if( CallStack.RunFilters( FilterText, OwnerWindow.Options.ClassGroups, bFilterIn, OwnerWindow.SelectedMemoryPool ) ) { string FunctionName = ""; int FirstStackFrameIndex; if( OwnerWindow.ContainersSplitButton.Text == " Show Containers" ) { FirstStackFrameIndex = CallStack.AddressIndices.Count - 1; } else { FirstStackFrameIndex = CallStack.FirstNonContainer; } do { FCallStackAddress Address = FStreamInfo.GlobalInstance.CallStackAddressArray[ CallStack.AddressIndices[ FirstStackFrameIndex ] ]; FunctionName = FStreamInfo.GlobalInstance.NameArray[ Address.FunctionIndex ]; FirstStackFrameIndex--; } while( UnhelpfulCallSites.Contains( FunctionName ) && FirstStackFrameIndex > 0 ); string SizeInKByte = String.Format( "{0:0}", ( float )AllocationInfo.Size / 1024 ).PadLeft( 10, ' ' ); string SizePercent = String.Format( "{0:0.00}", ( float )AllocationInfo.Size / TotalSize * 100 ).PadLeft( 10, ' ' ); string Count = String.Format( "{0:0}", AllocationInfo.Count ).PadLeft( 10, ' ' ); string CountPercent = String.Format( "{0:0.00}", ( float )AllocationInfo.Count / TotalCount * 100 ).PadLeft( 10, ' ' ); string GroupName = ( CallStack.Group != null ) ? CallStack.Group.Name : "Ungrouped"; string[] Row = new string[] { SizeInKByte, SizePercent, Count, CountPercent, GroupName, FunctionName }; ListViewItem Item = new ListViewItem( Row ); Item.Tag = AllocationInfo; ExclusiveListView.Items.Add( Item ); } } } var ColumnSorter = new MainWindow.FColumnSorter(); ColumnSorter.ColumnSortModeAscending = false; ColumnSorter.ColumnToSortBy = 0; ExclusiveListView.ListViewItemSorter = ColumnSorter; // Assignment automatically calls Sort ExclusiveListView.SetSortArrow( ColumnSorter.ColumnToSortBy, ColumnSorter.ColumnSortModeAscending ); ExclusiveListView.EndUpdate(); OwnerWindow.ToolStripProgressBar.Visible = false; }
private void OnTimerTick(object sender, EventArgs e) { try { if (_lock.TryEnterReadLock(_timer.Interval / 2)) { try { if (listView.Items.Count > 1000) { listView.Items.Clear(); } if (_queue.Count > 0) { bool beginUpdate = false; do { while (_skipped.ContainsKey(_index)) { _index++; } Line line; if (!_queue.TryGetValue(_index, out line)) { break; } if (!beginUpdate) { beginUpdate = true; listView.BeginUpdate(); } double seconds = (double)line.Ticks / Stopwatch.Frequency; string log = string.Format("{0}, {1}, {2}, [{3}]{4}\r", line.Index.ToString(), DateTime.Now, line.ProcessName, line.Pid, line.Text); //Logger.Instance.WriteLog(log); logger.Info(log); // split list into multiple string[] lines = line.Text.Split(new char[] { '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries); ListViewItem lastItem = null; for (int i = 0; i < lines.Length; i++) { ListViewItem item; if (i == 0) { item = new ListViewItem(line.Index.ToString()); item.SubItems.Add(seconds.ToString("0.00000000")); string name; if (line.ProcessName != null) { if (_settings.ShowProcessId) { name = line.ProcessName + " (" + line.Pid + ")"; } else { name = line.ProcessName; } } else { name = line.Pid.ToString(); } if (line.Description != null && _settings.ShowEtwDescription) { name += " (" + line.Description + ")"; } item.SubItems.Add(name); } else { item = new ListViewItem(string.Empty); item.SubItems.Add(string.Empty); item.SubItems.Add(string.Empty); } item.SubItems.Add(lines[i]).Name = TextItemName; // note: we don't use Tag to store line objects as we want to save memory here listView.Items.Add(item); lastItem = item; if (line.Pid == _processId) { foreach (ListViewItem.ListViewSubItem si in item.SubItems) { si.BackColor = Color.Red; } } } _queue.Remove(_index); _index++; if (lastItem != null && autoScrollToolStripMenuItem.Checked) { lastItem.EnsureVisible(); } }while (true); if (beginUpdate) { listView.EndUpdate(); } } } finally { _lock.ExitReadLock(); } } } catch (Exception ex) { Log("OnTimerTick Exception: " + ex); } }