我想在 C# 中获取对象/变量的创建者线程 ID



我正在使用C#多线程,我想将当前的threadId所有者threadId进行比较,即。

using System;
using System.Threading;
using System.Collections.Generic;
public class Program
{
static List<int> collection;
public static void Main()
{
int managedThreadId = Thread.CurrentThread.ManagedThreadId;
collection = new List<int>();       
Thread t1 = new Thread(UpdateMethod);
t1.Start();
}
public static void UpdateMethod()
{
Console.WriteLine(Thread.CurrentThread.ManagedThreadId);
Console.WriteLine(GetCreatorThread(collection));//Looking this kind of method so I can compare current thread to owner thread
}
}

.Net 框架在 WinForm 中做了类似的工作

大多数对象与创建它们的线程没有关联。System.Windows.Forms命名空间(即 Winforms)和System.Windows.Controls命名空间(即 WPF)中的某些对象或与 命名空间相关的某些对象会这样做,原因非常特殊,与这些对象如何与本机 Windows API 交互有关。这种线程亲和性存在于许多其他 API 中,尤其是与 GUI 相关的 API。

但这些都是特例。要跟踪用于创建它的线程的任何类型,该类型都必须显式实现该行为(如 Winforms 对象中看到的那样)。List<T>类没有理由绑定到特定线程,因此该类型中没有任何内容可以跟踪用于创建它的线程。

如果你想要一个列表类型来跟踪用于创建它的线程,你必须创建自己的列表类型。当然,您可以为此目的继承List<T>。例如:

class ThreadList<T> : List<T>
{
public int ThreadId { get; } = Thread.CurrentThread.ManagedThreadId;
// add your constructors here...
}

但事实是,你的问题似乎是一个XY问题。也就是说,您只需要知道用于创建对象的线程。对于不跟踪创建它们的线程的对象,没有"所有者线程"这样的东西。创建对象后,可以自由地将其与需要它的任何线程一起使用。

从您的问题中不清楚为什么您认为您需要知道创建对象的线程。可能您误以为该对象在假设的"所有者线程"中的行为与其他线程中的行为不同,或者您可能认为在"正确"线程中使用对象可能来自某种类型的线程安全(或者在"错误"线程中使用缺乏线程安全性)。或者也许是完全不同的东西。

如果您可以提出一个不同的问题,您可能会得到更好的服务,其中您解释为什么您认为您需要这些信息以及您打算具体用它做什么。

延伸阅读:
为什么某些对象无法从不同的线程访问?
在创建对象的
线程上调用方法 C#
中的每线程内存管理每个 CLR 或每个进程都有一个托管堆吗?

前两个链接讨论对象绑定到特定线程的方案。它们可以帮助您更好地理解这些方案,并了解为什么线程相关性不适用于所有对象。

上面的最后两个讨论了一种可能的方法,该方法可能会解决您要查找的任何问题。也就是说,虽然您无法在代码中轻松获取此信息,但如果在某些平台上启用服务器模式垃圾回收,您可能会发现根据分配对象的线程在不同的堆中分配的对象,并且此信息可能会显示在内存分析方案中。

最新更新