Use a Profiler in tracing mode. Then you will see how everything does call each other and where the time is spent. Besides commercial profilers there are also free ones.
For managed code there is NP Profiler which is quite good.
If you want to go deeper you can use the Windows Performance Toolkit which gives you full information accross all threads and how the interact with each other if you want to know. The only difference is that you get stacks ranging from kernel until your managed frames.
If this is not enough you can instrument your code with a tracing library (either automatically with PostSharp, ....) or manually or with a macro for each source file.
I have made a little tracing library which is quite fast and highly configurable. See here. As unique feature it can trace any thrown exception automatically.
private void SomeOtherMethod()
{
using (Tracer t = new Tracer(myType, "SomeOtherMethod"))
{
FaultyMethod();
}
}
private void FaultyMethod()
{
throw new NotImplementedException("Hi this a fault");
}
Here comes the output:
18:57:46.665 03064/05180 <{{ > ApiChange.IntegrationTests.Diagnostics.TracingTests.SomeMethod
18:57:46.668 03064/05180 <{{ > ApiChange.IntegrationTests.Diagnostics.TracingTests.SomeOtherMethod
18:57:46.670 03064/05180 < }}< ApiChange.IntegrationTests.Diagnostics.TracingTests.SomeOtherMethod Exception thrown: System.NotImplementedException: Hi this a fault
at ApiChange.IntegrationTests.Diagnostics.TracingTests.FaultyMethod()
at ApiChange.IntegrationTests.Diagnostics.TracingTests.SomeOtherMethod()
at ApiChange.IntegrationTests.Diagnostics.TracingTests.SomeMethod()
at ApiChange.IntegrationTests.Diagnostics.TracingTests.Demo_Show_Leaving_Trace_With_Exception()
18:57:46.670 03064/05180 < }}< ApiChange.IntegrationTests.Diagnostics.TracingTests.SomeOtherMethod Duration 2ms 18:57:46.689 03064/05180 < }}< ApiChange.IntegrationTests.Diagnostics.TracingTests.SomeMethod Duration 24ms