【问题标题】:How to enumerate all Tasks like Visual Studio Task window如何枚举所有任务,如 Visual Studio 任务窗口
【发布时间】:2016-05-17 21:30:09
【问题描述】:

我正在围绕我正在开发的服务器应用程序制作一个包装器,它显示调试信息,例如内存、cpu 使用情况、线程和任务、堆信息等,并提供一些启动和停止服务器的方法。

Visual Studio 有一个方便的任务窗口,用于调试异步应用程序。它提供以下信息:ID、状态、开始时间、持续时间和位置,以及位置。 是否有可能从我的应用程序中获取相同的信息?我愿意接受各种反射、黑客攻击和未记录的脏东西来获取这些信息,因为它不是生产代码。

我尝试在 TaskScheduler.Default 对象(这是一个 ThreadPoolTaskScheduler 对象)上执行内部方法 GetScheduledTasksForDebugger,但返回了 0 个任务,即使 Visual Studio 任务窗口显示至少安排了两个任务.

Visual Studio 任务窗口:

【问题讨论】:

  • 你可能做不到。
  • Visual Studio 显然可以,所以我相信这是可能的。它可能只需要一些淫秽的 P/Invoke、COM 包装、Roslyn 魔法或 Microsoft.Diagnostics.Runtime 项目。
  • 如果有的话,它需要一个调试器(必须是一个单独的进程)
  • 这似乎是一个编写调试器的教程。它可能会为您指明正确的道路? codeproject.com/Articles/43682/Writing-a-basic-Windows-debugger
  • 这是一条路吗?我试图实现监听器,但我没有得到事件回调。 stackoverflow.com/questions/28540728/…

标签: c# .net multithreading


【解决方案1】:

在 CodePlex 上有一个 TaskScheduler 的托管包装器。

并且使用该包装器可以枚举任务:

using System;
using Microsoft.Win32.TaskScheduler;

namespace ListTasks
{
    class Program
    {
        static void EnumFolderTasks(TaskFolder fld)
        {
            foreach (Task task in fld.Tasks)
                DisplayTask(task);

            foreach (TaskFolder sfld in fld.SubFolders)
                EnumFolderTasks(sfld);
        }

        static void DisplayTask(Task t)
        {
            Console.WriteLine("Task: {0, -60} Active: {1, -5} Enabled: {2, -5}", 
                              t.Name, t.IsActive, t.Enabled);
        }

        static void Main(string[] args)
        {
            using (TaskService ts = new TaskService())
            {
                EnumFolderTasks(ts.RootFolder);
            }
        }
    }
}

至于 Id、Status、Start time、Duration 和 Location 信息是否可用,我不确定。

但查看 Task 对象的定义,它确实包含大量信息,乍一看,其中大部分信息似乎都是可用的:

编辑:添加命名空间以消除对 Task 对象的一些混淆。

namespace Microsoft.Win32.TaskScheduler
{ 
    public class Task : IDisposable
    {
        public TaskDefinition Definition { get; }
        public bool Enabled { get; set; }
        public TaskFolder Folder { get; }
        public bool IsActive { get; }
        public DateTime LastRunTime { get; }
        public int LastTaskResult { get; }
        public string Name { get; }
        public DateTime NextRunTime { get; }
        public int NumberOfMissedRuns { get; }
        public string Path { get; }
        public bool ReadOnly { get; }
        public GenericSecurityDescriptor SecurityDescriptor { get; set; }
        public virtual TaskState State { get; }
        public TaskService TaskService { get; }
        public string Xml { get; }
        public void Dispose();
        public void Export(string outputFileName);
        public TaskSecurity GetAccessControl();
        public TaskSecurity GetAccessControl(AccessControlSections includeSections);
        public RunningTaskCollection GetInstances();
        public DateTime GetLastRegistrationTime();
        public DateTime[] GetRunTimes(DateTime start, DateTime end, uint count = 0);
        public string GetSecurityDescriptorSddlForm(SecurityInfos includeSections = SecurityInfos.Owner | SecurityInfos.Group | SecurityInfos.DiscretionaryAcl);
        public void RegisterChanges();
        public RunningTask Run(params string[] parameters);
        public RunningTask RunEx(TaskRunFlags flags, int sessionID, string user, params string[] parameters);
        public void SetAccessControl(TaskSecurity taskSecurity);
        public void SetSecurityDescriptorSddlForm(string sddlForm, TaskSetSecurityOptions options = TaskSetSecurityOptions.None);
        public void ShowPropertyPage();
        public void Stop();
        public override string ToString();
    }
}    

【讨论】:

  • 对不起,我问的不是 Windows 任务计划程序,而是 C# 任务 API,这是完全不同的东西。
  • 这不是 C# 任务 API(特别是 TPL 库)中的任务对象。它只是我链接到的 C# 托管项目的一部分的 Task 对象。该托管库只是您所指的 Windows 任务计划程序层的 C# 包装器。
  • @jussij 你搞错了,操作不是指 Windows 任务调度程序,而是指 Visual Studio 中的任务视图(用于运行任务 api 的任务)。他知道您指的是调度程序的任务对象,而不是任务 api,但他提到整个答案是题外话
猜你喜欢
  • 2022-08-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-11-06
  • 1970-01-01
  • 2018-10-23
  • 1970-01-01
  • 2011-09-01
相关资源
最近更新 更多