How can I assign a name to a task in TPL

后端 未结 11 1258
礼貌的吻别
礼貌的吻别 2021-02-12 10:24

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 wi

相关标签:
11条回答
  • 2021-02-12 11:06

    I dont think you can name the tasks. You can use Task.Id to track the tasks.

    0 讨论(0)
  • 2021-02-12 11:08

    If you only need to know the name of the task after the task is finished then you could just pass it as a parameter. Return it as a part of the task result.

        private async Task<string[]> MyTask(int x, string taskName)
        {
            return new[]
            {
                taskName, x.ToString()
            };
        }
    

    Or map your tasks to a dictionary

            var mapping = new Dictionary<Task, string>();
            var task = new Task(() => Console.WriteLine("myNullTask"));
            mapping.Add(task, "myNullTask");
            foreach (var taskX in mapping)
            {
                Console.WriteLine(
                    $"Task Id: {taskX.Key.Id}, " +
                    $"Task Name: {taskX.Value}, " +
                    $"Task Status: {taskX.Key.Status}");
            }
    
    0 讨论(0)
  • 2021-02-12 11:11

    Thanks to mike's answer I ended up with:

        public static class ExtensionMethods
        {
            private static readonly ConcurrentDictionary<WeakReference<Task>, object> TaskNames = new ConcurrentDictionary<WeakReference<Task>, object>();
    
            public static void _Tag(this Task pTask, object pTag)
            {
                if (pTask == null) return;
                var weakReference = ContainsTask(pTask) ?? new WeakReference<Task>(pTask);
                TaskNames[weakReference] = pTag;
            }
            public static void _Name(this Task pTask, string name)
            {
                _Tag(pTask, name);
            }
    
            public static object _Tag(this Task pTask)
            {
                var weakReference = ContainsTask(pTask);
                if (weakReference == null) return null;
                return TaskNames[weakReference];
            }
            public static object _Name(this Task pTask)
            {
                return (string)_Tag(pTask);
            }
    
            private static WeakReference<Task> ContainsTask(Task pTask)
            {
                foreach (var kvp in TaskNames.ToList())
                {
                    WeakReference<Task> weakReference = kvp.Key;
    
                    if (!weakReference.TryGetTarget(out var taskFromReference))
                    {
                        TaskNames.TryRemove(weakReference, out _);
                        //TaskNames.TryRemove(out ); //Keep the dictionary clean.
                        continue;
                    }
    
                    if (pTask == taskFromReference)
                    {
                        return weakReference;
                    }
                }
                return null;
            }
        }
    

    It is thread safe now and it also supports a name not just a tag.

    0 讨论(0)
  • 2021-02-12 11:14
    public class NamedTaskSchedular
    {
        private static readonly ConcurrentDictionary<string, NamesTask> NamedTaskDictionary = new ConcurrentDictionary<string, NamesTask>();
    
        public static Task RunNamedTask(string name, Action action)
        {
            if (NamedTaskDictionary.ContainsKey(name))
            {
                return NamedTaskDictionary[name].RunTask(action);
            }
            var task = new NamesTask();
    
            NamedTaskDictionary[name] = task;
    
            return task.RunTask(action);
        }
    }
    
    0 讨论(0)
  • 2021-02-12 11:15

    I'm shooting blind here as I don't know the behavior of Parallel Tasks window but if it uses the debugger api adding a DebuggerDisplay attribute on your NamedTask subclass might help

    0 讨论(0)
  • 2021-02-12 11:25

    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.

    0 讨论(0)
提交回复
热议问题