【问题标题】:How to tell if thread is running by its ID with C#如何使用 C# 判断线程是否通过其 ID 运行
【发布时间】:2013-05-20 10:37:56
【问题描述】:

我不确定这在托管代码中是否可行。让我解释。我需要通过它的 ID 知道一个特定的线程当前正在我的进程中运行。我可以从同一进程中的另一个线程执行此操作吗?

【问题讨论】:

  • @KaiWang:你能告诉我怎么做吗?

标签: c# multithreading


【解决方案1】:

我想你所说的 ID 是指托管 ID。简短的回答是没有直接的方法来枚举进程中的托管线程。在不同的进程中,您可以使用托管调试 API (MDbg) 附加到目标进程并从调试器的角度枚举所有托管线程。如果您可以启动一个单独的进程来执行此操作,这可能是最简单的方法。如果您必须从相同的过程中执行此操作,那也是可能的。但是您需要查看 MDbg 源代码。最新的 MDbg 支持附加到转储文件。您需要实现自己的 ICorDebugDataTarget 以支持实时进程。然后,您可以从同一进程访问您的进程,就像使用 MDbg 附加到转储文件一样。有一些限制,就像分析转储文件与分析实时进程不同。但它肯定会满足你的需求——枚举进程中的托管线程Id。

但正如我所说,如果您可以生成一个短暂的进程来完成这项工作,那是最简单的。

您可以从here下载MDbg源代码和示例。

【讨论】:

  • 我明白了。我能够通过使用 Win32(非托管)线程 ID 和线程创建时间来完成此操作。谢谢。
【解决方案2】:

您不能将 ProccessThread id 映射到托管线程 id,如 here 所述。

您无法枚举进程中的所有托管线程,如 here 所述。

如果您需要此功能,请维护您自己的托管线程 ID 集合。

【讨论】:

  • 如果 OP 只对他/她明确创建的线程感兴趣 - 而不是 ThreadPool 中的线程或由第三个库创建的线程,这会更容易。
  • @KaiWang - 我想这取决于 OP 所说的“线程当前正在运行”是什么意思。如果他的意思是“任务还没有完成”,那么不管它是通过Thread、ThreadPool、I/O控制端口等实现的,都可以被跟踪。如果他的意思是“在它的时间片中间调度程序,并且当前正在另一个 CPU/内核上执行”,那么不,这无法完成。
【解决方案3】:

我认为您不能使用托管线程来做到这一点。如果你真的需要这个功能,你可以通过使用显式创建的线程并通过创建自己的线程管理器来维护它们来完成你想要的。每次启动新线程时,您都可以为其分配一个 ID 并将其存储在字典中。这样,应该很容易通过其 ID 查找线程以从中获取所需的信息。当一个线程完成执行后,如果不再需要它,您可以将其从字典中删除。

public class ThreadManager
{
    private int threadID { get; set; }
    public Dictionary<int, Thread> ThreadList { get; set; }

    public ThreadManager()
    {
        this.ThreadList = new Dictionary<int, Thread>();
    }

    public void LaunchThread(Action<string> SomeProcess, string s)
    {
        Thread thread = new Thread(() => SomeProcess(s));
        int id = threadID++;
        thread.Name = id.ToString();
        ThreadList.Add(id, thread);
        thread.Start();
    }

    public void KillThread()
    {
        ThreadList.Remove(Int32.Parse(Thread.CurrentThread.Name));
    }
}

【讨论】:

    【解决方案4】:

    我在forum 中找到了这个:

    int threadId = [something];
    
    Process currentProcess = Process.GetCurrentProcess();
    
    foreach( Thread thread in currentProcess.Threads )
    {
        if( thread.ManagedThreadId.Equals( threadId ) )
        {
            // do something
        }
    }
    

    自己没试过。

    【讨论】:

    • 谢谢,但这行不通。我在foreach 行收到以下异常:System.InvalidCastException: Unable to cast object of type 'System.Diagnostics.ProcessThread' to type 'System.Threading.Thread'.
    • ProcessThread != 线程。 ProcessThread.Id 是本机线程 ID。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-12-12
    • 1970-01-01
    • 1970-01-01
    • 2012-07-31
    • 1970-01-01
    相关资源
    最近更新 更多