Rich 6a973a288b Added Objects DebugProfile and DebugDBTrack for command-line parameters /Profile and /DBTrack
Added code to retrieve command-line parameters.
Added property CalledFromCSLA to retrieve the CSLA object and method used by DBTracking.
Added ProfileTimer object to track CPU using by methods
2015-01-19 20:52:32 +00:00

227 lines
6.7 KiB
C#

using System;
using System.Collections.Generic;
using System.Text;
using System.Diagnostics;
namespace Volian.Base.Library
{
// This provides a more robust stack trace than what visual studio offers
public static class vlnStackTrace
{
public static string GetStack(string str, params object[] objects)
{
return string.Format(str, objects) + StackToString();
}
public static void ShowStack(string str, params object[] objects)
{
Console.WriteLine(string.Format(str, objects) + StackToString());
}
public static string GetStack()
{
return StackToString();
}
public static string GetStack(bool showSame)
{
return StackToString(showSame);
}
public static void ShowStack()
{
Console.WriteLine(StackToString());
}
private static string StackToString()
{
return StackToString(true);
}
private static string StackToString(bool showSame)
{
StringBuilder sb = new StringBuilder();
StackTrace st = new StackTrace(true);
StackFrame[] sfs = st.GetFrames();
int ii = 0;
string sLast = "";
string sThis = "";
int imax = MatchingStackFrame(sfs);
foreach (StackFrame sf in sfs)
{
if (showSame && imax == 0)
sb.Append(string.Format("\r\n{0}---------", "".PadLeft(ii++ * 2)));
imax--;
if (ii < 2) ii++;
else
{
string sMethod = sf.GetMethod().Name;
string sNamespace = sf.GetMethod().ReflectedType.Namespace;
string sType = sf.GetMethod().ReflectedType.Name;
if (sf.GetFileLineNumber() != 0)
{
sMethod += string.Format(" {0}[{1}]", sf.GetFileName(), sf.GetFileLineNumber());
sThis = "";
}
else
{
sThis = sNamespace;
}
if (sLast == sThis && sThis != "")
sb.Append(string.Format("\t*.{0}.{1}", sType, sMethod));
else
sb.Append(string.Format("\r\n{0}{1}.{2}.{3}", "".PadLeft(ii++ * 2), sNamespace, sType, sMethod));
}
sLast = sThis;
}
return sb.ToString();
}
public static void ShowStackLocal(string str, params object[] objects)
{
Console.WriteLine(string.Format(str, objects) + StackToStringLocal(2,10));
}
public static void ShowStackFirstLocal(string str)
{
Console.WriteLine(str + "\r\n" + StackToStringLocal(3, 0));
}
public static void ShowStackLocal(string str,int start)
{
Console.WriteLine(str + "\r\n" + StackToStringLocal(start,1));
}
public static void ShowStackLocal(string str,int start, int limit)
{
Console.WriteLine(str + "\r\n" + StackToStringLocal(start, limit));
}
public static string StackToStringLocal(int start, int limit)
{
StringBuilder sb = new StringBuilder();
string sep = "\r\n";
StackTrace st = new StackTrace(true);
StackFrame[] sfs = st.GetFrames();
int count = 0;
int localCount = 0;
foreach (StackFrame sf in sfs)
{
count++;
if (count > start)
{
if (sf.GetFileLineNumber() != 0)
{
string sMethod = sf.GetMethod().Name;
string sNamespace = sf.GetMethod().ReflectedType.Namespace;
string sType = sf.GetMethod().ReflectedType.Name;
sMethod += string.Format(" {0}[{1}]", sf.GetFileName(), sf.GetFileLineNumber());
sb.Append(sep + string.Format("{0}.{1}.{2}", sNamespace, sType, sMethod));
localCount ++;
if (localCount >= limit)
return sb.ToString();
sep = "\r\n" + "".PadRight(localCount *2);
}
}
}
if (localCount > 0)
return sb.ToString();
return "No Local Method";
}
public static string CalledFrom
{
get
{
StackTrace st = new StackTrace(true);
StackFrame[] sfs = st.GetFrames();
int count = 0;
foreach (StackFrame sf in sfs)
{
if (sf.GetFileLineNumber() != 0) // Only look at Local Methods
{
count++;
if (count > 4) // The fourth entry should be the Calling Method
{
string sType = sf.GetMethod().ReflectedType.Name;
string sMethod = sf.GetMethod().Name;
return string.Format("{0}.{1}[{2}]", sType, sMethod, sf.GetFileLineNumber());
}
}
}
return "No Local Method";
}
}
public static string CalledFromCSLA
{
get
{
StackTrace st = new StackTrace(true);
StackFrame[] sfs = st.GetFrames();
int count = 0;
string lastWasCSLA = null;
foreach (StackFrame sf in sfs)
{
string sType = sf.GetMethod().ReflectedType.FullName;
string sMethod = sf.GetMethod().Name;
if (sType.StartsWith("VEPROMS.CSLA.Library") && !sType.StartsWith("VEPROMS.CSLA.Library.Database")
&& !sMethod.StartsWith("DataPortal") && !sMethod.StartsWith("SetParentSectionAndDocVersion"))// Only look at Local Methods
lastWasCSLA = string.Format("{0}.{1}[{2}]", sType, sMethod, sf.GetFileLineNumber());
else
if (lastWasCSLA != null) return lastWasCSLA;
}
return "No CSLA Method";
}
}
private static StackFrame[] _LastSFS;
private static int MatchingStackFrame(StackFrame[] sfs)
{
int iFound = -1;
if (_LastSFS != null)
{
// start at the far end and work backward
for (int i = 1; iFound < 0 && i <= sfs.Length && i <= _LastSFS.Length; i++)
{
if (!Match(sfs[sfs.Length - i],_LastSFS[_LastSFS.Length - i]))
iFound = 1+ sfs.Length - i;
}
}
if (iFound < 0) iFound = sfs.Length;
_LastSFS = (StackFrame[])sfs.Clone();
return iFound;
}
private static bool Match(StackFrame stackFrame1, StackFrame stackFrame2)
{
if (stackFrame1.GetMethod().Name != stackFrame2.GetMethod().Name) return false;
if (stackFrame1.GetMethod().DeclaringType.FullName != stackFrame2.GetMethod().DeclaringType.FullName) return false;
if (stackFrame1.GetILOffset() != stackFrame2.GetILOffset()) return false;
return true;
}
public static bool ScrollInStack()
{
StackTrace st = new StackTrace(true);
StackFrame[] sfs = st.GetFrames();
bool retval = false;
foreach (StackFrame sf in sfs)
{
string sMethod = sf.GetMethod().Name;
string sNamespace = sf.GetMethod().ReflectedType.Namespace;
string sType = sf.GetMethod().ReflectedType.Name;
if (sMethod.ToUpper().Contains("SCROLL") || sType.ToUpper().Contains("SCROLL"))
{
retval = true;
Console.WriteLine("{0}.{1}.{2}", sNamespace, sType, sMethod);
}
}
return retval;
}
/// <summary>
/// This will clear the Output window when run in the Development Environment
/// Add EnvDTE and EnvDTE80 to references from .NET
/// </summary>
public static void ClearOutputWindow()
{
#if (DEBUG)
try
{
EnvDTE80.DTE2 dte2 = (EnvDTE80.DTE2)System.Runtime.InteropServices.Marshal.GetActiveObject("VisualStudio.DTE.8.0");
dte2.ToolWindows.OutputWindow.ActivePane.Clear();
}
catch (Exception ex)
{
Console.WriteLine("ClearOutputWindow {0} - {1}\r\n{2}", ex.GetType().Name, ex.Message, ex.StackTrace);
}
#endif
}
}
}