Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Tracking c#/.NET tasks flow

I'm trying to find a way to keep a track on async tasks execution flow in a way that it would be easy to understand regarding task, what was the original flow that initiated it. I need it mostly for logging, debugging and preserving a sort of stack trace for a specific execution flow.

For example: If I have a server with many clients from multiple IPs and the server needs to execute a work flow for each client that involves many async actions thus involves many different tasks per execution flow; logging such a flow is difficult especially when using async/await mechanism.

I haven't figured out a way to wrap the tasks in a way that for each task that is executed I would know the initial flow description when logging. For example if I start a new flow of tasks for an action with description - "Taking care of 10.0.3.4 client" I want to be able to add this description for each log item coming out from this flow in any task that created from it.

When using threads only, its easy because you have thread static variables. with tasks its impossible... I even tried to create my own task scheduler that will wrap out any task that uses it (even when using async/await methods) but got into a dead end because the task scheduler base sometimes uses new threads (even though there wasn't any implicit request to use a new thread)- the method TryExecuteTaskInline can sometimes run in a new thread.

Any idea or suggestion of how can I achieve that?

like image 868
ThaPhoeniX Avatar asked Jun 28 '14 16:06

ThaPhoeniX


People also ask

How do you identify a tracking number?

The tracking number is typically printed on the shipping label as a bar code that can be scanned by anyone with a bar code reader or smartphone. In the United States, some of the carriers using tracking numbers include UPS, FedEx, and the United States Postal Service.

What is C note number in courier?

What is C note number in courier? The "C" in C-note refers to the Roman numeral for 100, which was printed on $100 bills, and it can also refer to a century.

What tracking numbers start with CS?

A China Post EMS tracking number (shipment ID) has 13 characters. It starts with the letter “E” for Express Mail and ends with “CN” or “CS” with 9 digits in between. For epacket/EUB, the tracking number starts with “LK”. For China International Express, it begins with “CT”.)

How can I track my parcel with tracking number?

One of the ways is through the India Post SMS service. All you have to do for this is type send the typically 13-digit India Post tracking number via SMS on 166 or 51969. Alternatively, if you are online you can track your India Post delivery through the Ship24 website.


1 Answers

You can use Trace.CorrelationManager.ActivityId to store a logical operation id, or even better store an ImmutableStack of logical operation ids. It is stored in the CallContext and is copied through the async method calls:

public static class LogicalFlow
{
    private static readonly string _name = typeof (LogicalFlow).Name;

    private static ImmutableStack<Guid> LogicalStack
    {
        get
        {
            return CallContext.LogicalGetData(_name) as ImmutableStack<Guid> ?? ImmutableStack.Create<Guid>();
        }
        set
        {
            CallContext.LogicalSetData(_name, value);
        }
    }

    public static Guid CurrentId
    {
        get
        {
            var logicalStack = LogicalStack;
            return logicalStack.IsEmpty ? Guid.Empty : logicalStack.Peek();
        }
    }
}

You can use it as an IDisposable so you can utilize a using scope to make sure there's a Pop to every Push:

private static readonly Popper _popper = new Popper();

public static IDisposable StartScope()
{
    LogicalStack = LogicalStack.Push(Guid.NewGuid());
    return _popper;
}

private sealed class Popper : IDisposable
{
    public void Dispose()
    {
        LogicalStack = LogicalStack.Pop();
    }
}

Usage:

using (LogicalFlow.StartScope())
{
    Console.WriteLine(LogicalFlow.CurrentId);
    await DoSomethingAsync();
    Console.WriteLine(LogicalFlow.CurrentId);
}

This answer previously relied on Trace.CorrelationManager.LogicalOperationStack but Is LogicalOperationStack incompatible with async in .Net 4.5

like image 54
i3arnon Avatar answered Oct 06 '22 17:10

i3arnon