如何监视.NET TaskSchedulers中的任务队列(跨AppDomain)

时间:2015-04-09 22:03:08

标签: .net task-parallel-library task monitoring

作为开发人员,我想监视TaskSchedulers中任务队列中工作的大小(和进度),以便我可以评估生产负载下经历的减速是否是由于任务计划的大小或可能停滞

通常我只需附加调试器并检查任务大小,但是:

  1. 应用程序在单声道和正在制作中运行,所以我无法使用visual studio
  2. 附加它
  3. 我想提供有关此数据的分析输出作为服务健康监控的监控输入
  4. 我通过了文档并找到了

    • TaskScheduler.GetScheduledTasks,它将此信息提供给调试器。它受到保护(我可以规避),但似乎也需要一些我不能尊重的冻结线程的保证。但是,我愿意使用不一致的数据。
    • how to get a list of running tasks in .net 4.0。其中重点关注正在运行的任务,这对我来说并不那么有趣。我对积压的大小以及工作是否进展感兴趣。

    我愿意:

    1. 使用专为其他目的而设计的代码(例如调试器)
    2. 接受我得到的数据不一致(这是统计和分析)
    3. 想要做的事情是:

      1. 为每个创建的任务添加跟踪。
        • 部分代码是第三方,无法重构
        • 很多的代码,并且将其注入其中会比不能告诉它如何进展更糟糕。
      2. 使用自定义TaskScheduler
        • 部分代码是第三方,无法重构
        • 部分代码使用TaskSchedulers设置线程优先级和最大并发。在监控方面考虑因素会非常糟糕。

2 个答案:

答案 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花费的时间,空闲时间,任务切换计数等的统计数据......