c# - 如何为 TPL 中的任务分配名称

标签 c# task-parallel-library parallel.foreach

我将在我的应用程序上运行大量任务。由于某种原因,每组任务都在运行。我想给这些任务命名,这样当我查看“并行任务”窗口时,我可以很容易地识别它们。

从另一个角度来看,假设我在框架级别使用任务来填充列表。使用我的框架的开发人员也在为她的工作使用任务。如果她查看并行任务窗口,她会发现一些任务不知道。我想给任务命名,这样她就可以区分框架任务和她的任务。

如果有这样的API就很方便了:

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

或者也许:

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

甚至在使用 Parallel.ForEach

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

是否可以给任务命名?

是否可以为 ‍‍‍Parallel.ForEach 提供一个命名结构(可能使用 lambda)以便它创建具有该命名的任务?

是否有我缺少的 API?


我还尝试使用继承的任务来覆盖它的 ToString()。但不幸的是,Parallel Tasks 窗口不使用 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;
    }
}

最佳答案

您可以将任何对象与任何对象联系起来。这是任务的扩展。它使用弱引用,因此当所有引用都超出范围时,任务仍然可以被垃圾回收。

用法:

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

扩展类:

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;
    }
}

关于c# - 如何为 TPL 中的任务分配名称,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13762286/

相关文章:

c# - 使用 Parallel.ForEach() 时防止远程系统过载

c# - TPL 如何确定要使用的线程数?

c# - 使用 Shift+F5 终止运行后返回编码 Pane 的 Visual Studio 快捷方式

c# - 从旧字典填充新字典

c# - DateTime 转换为 Unix Epoch 添加 Phantom Hour

c# - 如何使用 Parallel.ForEach 正确写入文件?

c# parallel foreach 循环查找索引

c# - 在 JavaScript 中传递参数

c# - 继续 Task<T> 时保留异常

azure - for-each 在 azure 数据工厂中一次传递所有文件