作为开发人员,我想监视TaskSchedulers中任务队列中工作的大小(和进度),以便我可以评估生产负载下经历的减速是否是由于任务计划的大小或可能停滞
通常我只需附加调试器并检查任务大小,但是:
我通过了文档并找到了
我愿意:
我不想要做的事情是:
答案 0 :(得分:1)
不幸的是TaskScheduler.GetScheduledTasks
仅适用于调试器,并且没有直接的方法来获取计划任务。
但是MSDN说(source):
实现自定义调试器的开发人员不应直接调用此方法,而应使用内部包装器方法
GetScheduledTasksForDebugger
代替:internal Task[] GetScheduledTasksForDebugger()
。此包装器方法返回一组任务而不是可枚举的任务。要检索活动调度程序列表,请使用内部方法internal static TaskScheduler[] GetTaskSchedulersForDebugger()
。此静态方法返回所有活动TaskScheduler实例的数组。然后,您可以在每个调度程序实例上使用GetScheduledTasksForDebugger
来检索其计划任务列表。
那么为什么不使用反射呢?这是一种安全简便的方法来实现您的目标,因为将来会存在GetScheduledTasksForDebugger
,它专为调试而设计,可能用于分析。
答案 1 :(得分:1)
我可以使用反射和GetScheduledTasksForDebugger检索信息:
public static class ScheduledTaskAccess
{
public static Task[] GetScheduledTasksForDebugger(this TaskScheduler ts)
{
var mi = ts.GetType().GetMethod("GetScheduledTasksForDebugger", BindingFlags.NonPublic | BindingFlags.Instance);
if (mi == null)
return null;
return (Task[])mi.Invoke(ts, new object[0]);
}
public static TaskScheduler[] GetTaskSchedulersForDebugger()
{
var mi = typeof(TaskScheduler).GetMethod("GetTaskSchedulersForDebugger", BindingFlags.NonPublic | BindingFlags.Static);
if (mi == null)
return null;
return (TaskScheduler[])mi.Invoke(null, new object[0]);
}
}
使用自定义IEqualityComparer我能够维持它们排队的时间。非常有用的元信息:)
现在我只希望有一些关于可以访问的任务,CPU花费的时间,空闲时间,任务切换计数等的统计数据......