我将在我的应用程序上运行大量任务。由于某种原因,每组任务都在运行。我想给这些任务命名,这样当我查看“并行任务”窗口时,我可以很容易地识别它们。
从另一个角度来看,假设我在框架级别使用任务来填充列表。使用我的框架的开发人员也在为她的工作使用任务。如果她查看并行任务窗口,她会发现一些任务不知道。我想给任务命名,这样她就可以区分框架任务和她的任务。
如果有这样的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/