If your code is performing slowly and you're not sure why, a useful analysis technique is to add some diagnostic logging around blocks of code you suspect might be slow and to report how much time is spent in those code blocks. System.Diagnostics provides a number of tools which can be used, including the Stopwatch class for high-resolution timing and the Trace class for sending output to various TraceListeners. When an application is running in debug mode, Visual Studio attaches a ConsoleTraceListener to the Output window for you, so any trace output, such as from calling System.Diagnostics.Trace.WriteLine(), will be visible there. It's also possible, using settings in App.Config or Web.Config, to send trace output to other places, such as text files or the Windows Event log.
The AB_LogicalOperationScope class makes it easy to wrap a block of code with tracing, with a start time, end time, duration, and nested logging. To use it, wrap the code to diagnose in a using block. These blocks can be nested, which will cause the log entries to be indented to show the nesting:
protected override void am_AsyncSearchCompleted(System.Collections.IList EntityRecords, AB_SelectReturnArgs SelectReturnArgs) { using (new AB_LogicalOperationScope("am_AsyncSearchCompleted")) { using (new AB_LogicalOperationScope("Call base.am_AsyncSearchCompleted")) { base.am_AsyncSearchCompleted(EntityRecords, SelectReturnArgs); } using (new AB_LogicalOperationScope("Call _LoadTree after async search")) { // Load Tree _LoadTree(); } if (_SelectedModule == null) return; using (new AB_LogicalOperationScope("Set ap_SelectedItem properties after async search")) { foreach (AB_BusinessObjectEntityBase item in ap_DataPresenter.ap_Items.Cast<ab_businessobjectentitybase>().Where(item => item.ap_CompleteUniqueKey == _SelectedModule.ap_CompleteUniqueKey)) { ap_DataPresenter.ap_SelectedItem = item; break; } } } }</ab_businessobjectentitybase>
This method's log trace will look like this:
[171318832883] START am_AsyncSearchCompleted
[171318888188] START Call base.am_AsyncSearchCompleted
[171319062011] FINISH (66.916909ms) Call base.am_AsyncSearchCompleted
[171319074116] START Call _LoadTree after async search
[171319095415] START _LoadTree - 142ab766-fc33-43be-8032-8331bba53513
[171319104210] START Set expanded flag and event handler - 142ab766-fc33-43be-8032-8331bba53513
[171319114309] FINISH (3.891454ms) Set expanded flag and event handler - 142ab766-fc33-43be-8032-8331bba53513
[171319131723] START Add modules to recordSet - 142ab766-fc33-43be-8032-8331bba53513
[171319143700] FINISH (4.614388ms) Add modules to recordSet - 142ab766-fc33-43be-8032-8331bba53513
[171319171338] START Call ap_DataTransform for 3 records - 142ab766-fc33-43be-8032-8331bba53513
[171319216930] FINISH (17.554848ms) Call ap_DataTransform for 3 records - 142ab766-fc33-43be-8032-8331bba53513
[171319230210] FINISH (51.892719ms) _LoadTree - 142ab766-fc33-43be-8032-8331bba53513
[171319236621] FINISH (62.559667ms) Call _LoadTree after async search
[171319240466] FINISH (156.903067ms) am_AsyncSearchCompleted