After reviewing your question again I don't see how the object in question is really a Message, unless it is more like a tracing message (for debugging assistance).
If you're looking for something more along those lines then here is a very rough approach using delegates. Essentially you create a delegate for each method you want to call and time, then pass the delegate and the method arguments off to a helper who is responsible for the actual calling of the method and timing its duration.
The obvious shortcoming in my example is that I sacrificed type-safe arguments since I wasn't sure if it was exactly what you're looking for or not. The other issue is that you would need to add a new delegate every time you want to call a method which has a method signature that you don't already have a delegate for:
using System;
namespace ConsoleApplication4
{
class Program
{
static void Main(string[] args)
{
SomeCaller callerOne;
YetAnotherCaller callerTwo;
callerOne = new SomeCaller(SomeMethod);
LogCallDuration(callerOne, new object[] { 15 });
callerOne = new SomeCaller(SomeOtherMethod);
LogCallDuration(callerOne, new object[] { 22 });
callerTwo = new YetAnotherCaller(YetAnotherMethod);
LogCallDuration(callerTwo, null);
Console.ReadKey();
}
#region "Supporting Methods/Delegates"
delegate void SomeCaller(int someArg);
delegate void YetAnotherCaller();
static void LogCallDuration(Delegate targetMethod, object[] args)
{
DateTime start = DateTime.UtcNow;
targetMethod.DynamicInvoke(args);
DateTime stop = DateTime.UtcNow;
TimeSpan duration = stop - start;
Console.WriteLine(string.Format("Method '{0}' took {1}ms to complete", targetMethod.Method.Name, duration.Milliseconds));
}
#endregion "Supporting Methods/Delegates"
#region "Target methods, these don't have to be in your code"
static void SomeMethod(int someArg)
{
// Do something that takes a little time
System.Threading.Thread.Sleep(1 + someArg);
}
static void SomeOtherMethod(int someArg)
{
// Do something that takes a little time
System.Threading.Thread.Sleep(320 - someArg);
}
static void YetAnotherMethod()
{
// Do something that takes a little time
System.Threading.Thread.Sleep(150);
}
#endregion "Target methods"
}
}