Implementation Class: DianosticsDurationHelper
To calculation duration between two debug calls, I created an implementation class: DianosticsDurationHelper. In addition to two public properties in the base class, the implementation class provides a few public methods.
As you can see, the duration helper class has very simple APIs. One method Indent() is used for indentation or un-indentation, and one method for debug a message. The duration calculation is done within the class.
As discussed above, the calculation is done through delegates. Two private methods are defined here. One is for obtaining the current date time value, and another for calculating the duration value. Those methods are used as delegates to the base class calls.
private DateTime GetDateTime()
{
return DateTime.Now;
}
private string CalculateDuration(DateTime dt, DateTime poppedValue)
{
float duration = (float)((new TimeSpan(dt.Ticks - poppedValue.Ticks)).Hours) * 3600.0f +
(float)((new TimeSpan(dt.Ticks - poppedValue.Ticks)).Minutes) * 60.0f +
(float)((new TimeSpan(dt.Ticks - poppedValue.Ticks)).Seconds) +
(float)((new TimeSpan(dt.Ticks - poppedValue.Ticks)).Milliseconds) / 1000.0f;
return string.Format(" duration: {0:N2}", duration);
}
The remaining part of the duration helper class is as followings:
internal class DianosticsDurationHelper : DianosticsHelperBase<DateTime>
{
public DianosticsDurationHelper(string className) : base(className)
{
}
public DianosticsDurationHelper DebugMessage(string message)
{
base.debugMessageBase(message);
return this;
}
public DianosticsDurationHelper Indent()
{
return DebugIndent(true);
}
public DianosticsDurationHelper UnIndent()
{
return DebugIndent(false);
}
private DianosticsDurationHelper DebugIndent(bool indent)
{
if (indent)
{
base.debugIndent(GetDateTime);
}
else
{
base.debugUnindent(GetDateTime, CalculateDuration);
}
return this;
}
...// private methods used as delegates, see above.
}
Usage Examples
In many of projects, I used this duration class to get duration time between the begging and end of each call. Here are some example codes.
[STAThread]
static void Main() {
// customize indent string to --
DiagnosticsDurationHelper.IndentString = "--";
MyForm mainForm = new MyForm();
Application.Run(mainForm);
// ...
}
// MyForm.cs
class MyForm : Form {
// some helper methods using duration helper class
private DianosticsDurationHelper _debugHelper =
new DianosticsDurationHelper("MyForm");
// other data members
// helper methods to use the debug instance
private void DebugMessage(string message) {
_debugHelper.DebugMessage(message);
}
private void DebugMessage(string message, bool indent) {
if (indent) {
_debugHelper.DebugMessage(message).Indent();
}
else {
_debugHelper.UnIndent().DebugMessage(message);
}
}
// use debug helper methods to log duration...
private void MyForm_Load(object sender, EventArgs e) {
DebugMessage("MyForm_Load", true);
// ...
DebugMessage("Some information...");
// ...
DebugMessage("MyForm_Load", false);
}
// ...
}
By the way, in my helper class and base class, I tried to use fluent interface pattern for APIs. As you can see, the usage of those APIs is much fluent and clean.
To get the debug result in my Visual Studio's output console, I run my application in debug mode. Alle debug strings will be in the output console. Here are some results:
--[ 10/18/2010 11:21:58 AM ] MyForm::MyForm_Load
----[ 10/18/2010 11:23:58 AM ] DBGateway::DBGateway
...
----[ 10/18/2010 11:23:58 AM duration: 0.02 ] DBGateway::DBGateway
--[ 10/18/2010 11:22:58 AM ] MyForm::Some information ...
...
--[ 10/18/2010 11:21:58 AM duration: 0.22 ] MyForm:: MyForm_Load
Here is the source codes with an example.