Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I assign a name to a task in TPL

I'm going to use lots of tasks running on my application. Each bunch of tasks is running for some reason. I would like to name these tasks so when I watch the Parallel Tasks window, I could recognize them easily.

With another point of view, consider I'm using tasks at the framework level to populate a list. A developer that use my framework is also using tasks for her job. If she looks at the Parallel Tasks Window she will find some tasks having no idea about. I want to name tasks so she can distinguish the framework tasks from her tasks.

It would be very convenient if there was such API:

var task = new Task(action, "Growth calculation task")

or maybe:

var task = Task.Factory.StartNew(action, "Populating the datagrid")

or even while working with Parallel.ForEach

Parallel.ForEach(list, action, "Salary Calculation Task"

Is it possible to name a task?

Is it possible to give ‍‍‍Parallel.ForEach a naming structure (maybe using a lambda) so it creates tasks with that naming?

Is there such API somewhere that I'm missing?


I've also tried to use an inherited task to override it's ToString(). But unfortunately the Parallel Tasks window doesn't use ToString()!

class NamedTask : Task
{
    private string TaskName { get; set; }
    public NamedTask(Action action, string taskName):base(action)
    {
        TaskName = taskName;
    }

    public override string ToString()
    {
        return TaskName;
    }
}
like image 965
mehrandvd Avatar asked Dec 07 '12 11:12

mehrandvd


People also ask

What is TPL Task Parallel Library?

The Task Parallel Library (TPL) is a set of public types and APIs in the System. Threading and System. Threading. Tasks namespaces. The purpose of the TPL is to make developers more productive by simplifying the process of adding parallelism and concurrency to applications.

Should I use Task or thread?

It is always advised to use tasks instead of thread as it is created on the thread pool which has already system created threads to improve the performance. The task can return a result. There is no direct mechanism to return the result from a thread. Task supports cancellation through the use of cancellation tokens.

How do I create a new Task in C#?

To start a task in C#, follow any of the below given ways. Use a delegate to start a task. Task t = new Task(delegate { PrintMessage(); }); t. Start();

How are threads different from TPL?

Compared to the classic threading model in . NET, Task Parallel Library minimizes the complexity of using threads and provides an abstraction through a set of APIs that help developers focus more on the application program instead of focusing on how the threads will be provisioned.


3 Answers

You could relate any object with any object. Here is an extension for Task. It uses a WeakReference so the task can still be garbage collected when all references are out of scope.

Usage:

var myTask = new Task(... myTask.Tag("The name here"); var nameOfTask = (string)myTask.Tag(); 

Extension class:

public static class TaskExtensions {     private static readonly Dictionary<WeakReference<Task>, object> TaskNames = new Dictionary<WeakReference<Task>, object>();       public static void Tag(this Task pTask, object pTag)     {         if (pTask == null) return;         var weakReference = ContainsTask(pTask);         if (weakReference == null)         {             weakReference = new WeakReference<Task>(pTask);         }         TaskNames[weakReference] = pTag;     }      public static object Tag(this Task pTask)     {         var weakReference = ContainsTask(pTask);         if (weakReference == null) return null;         return TaskNames[weakReference];     }      private static WeakReference<Task> ContainsTask(Task pTask)     {         foreach (var kvp in TaskNames.ToList())         {             var weakReference = kvp.Key;              Task taskFromReference;             if (!weakReference.TryGetTarget(out taskFromReference))             {                 TaskNames.Remove(weakReference); //Keep the dictionary clean.                 continue;             }              if (pTask == taskFromReference)             {                 return weakReference;             }         }         return null;     } } 
like image 75
Mike de Klerk Avatar answered Oct 17 '22 08:10

Mike de Klerk


You can't really name a Task, but you can name the method which is executed by a Task, which is then shown in the Parallel Tasks windows. So, if naming the Tasks is important for you, don't use lambdas, use normal named methods.

Surprisingly, this works even with Parallel, even though there the Task isn't executing your method directly. I think this is because Parallel Tasks somehow knows about Tasks from Parallel and handles them differently.

like image 26
svick Avatar answered Oct 17 '22 07:10

svick


You can't name tasks.

The task library is internally using a thread pool, so the threads can't be named. Also your inheritance approach won't work, because methods like ".ContinueWith()" will always create a new task, which won't inherit from your class.

like image 36
JustAnotherUserYouMayKnow Avatar answered Oct 17 '22 07:10

JustAnotherUserYouMayKnow