Reputation: 16743
I am trying to disentangle my logs by grouping my log messages together. Ideally, I'd append to each message some identifier indicating that it is part of a group of commands achieving some piece of work.
If this were a single threaded application, the thread's ID would be a candidate. However, this solution makes heavy use of async Task
s, which precludes its use. Is it possible to get something like the following to work, where every execution of Main()
would always print out the same thread ID?
static async void Main()
{
var t = Task.Run(async () => await MyAsyncMethod());
await t;
}
private static async Task MyAsyncMethod()
{
Debug.WriteLine("Log message: {0}", Thread.CurrentThread.ManagedThreadId);
await Task.Delay(1000);
Debug.WriteLine("Log message: {0}", Thread.CurrentThread.ManagedThreadId);
await Task.Delay(1000);
Debug.WriteLine("Log message: {0}", Thread.CurrentThread.ManagedThreadId);
}
Upvotes: 1
Views: 904
Reputation: 457177
The best approach IMO is what @SriramSakthivel suggested: just generate an id and pass it around. If you have a "message" type, you could just add it to that type.
However, if this would cause too much of a code change, then you can pass it implicitly. I have a blog post with the gory details; the general idea is that you store the data as part of the logical call context:
public static class MyContext
{
private static readonly string name = Guid.NewGuid().ToString("N");
private sealed class Wrapper : MarshalByRefObject
{
public Guid Value { get; set; }
}
public static Guid CurrentContext
{
get
{
var ret = CallContext.LogicalGetData(name) as Wrapper;
return ret == null ? Guid.Empty : ret.Value;
}
set
{
CallContext.LogicalSetData(name, new Wrapper { Value = value });
}
}
}
Then you can use it from your code as such:
private static async Task MyAsyncMethod()
{
MyContext.CurrentContext = Guid.NewGuid();
Debug.WriteLine("Log message: {0}", MyContext.CurrentContext);
await Task.Delay(1000);
Debug.WriteLine("Log message: {0}", MyContext.CurrentContext);
await Task.Delay(1000);
Debug.WriteLine("Log message: {0}", MyContext.CurrentContext);
}
Note that this approach makes two crucial assumptions:
Guid
is immutable).It looks like something like this will be builtin in .NET 4.6.
Upvotes: 4