线程重命名

NT_*_*NT_ 14 .net c# multithreading

在Java中,可以重命名线程.在.NET中它不是.这是因为Name是Thread类中一次写入的属性:

public string Name
{
    get
    {
        return this.m_Name;
    }
    [HostProtection(SecurityAction.LinkDemand, ExternalThreading=true)]
    set
    {
        lock (this)
        {
            if (this.m_Name != null)
            {
                throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_WriteOnce"));
            }
            this.m_Name = value;
            InformThreadNameChangeEx(this, this.m_Name);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

鉴于Java允许线程重命名并且所使用的大多数底层线程结构都是在两个平台上提供操作系统,我倾向于认为我实际上可以在C#中重命名线程,如果我避免使用某些功能)我不在乎或b)根本不使用.

你知道为什么Thread重命名是一次写入操作吗?如果更改名称有什么想法吗?

我尝试过一个测试,我将线程重命名为:

var t1 = new Thread(TestMethod);
t1.Name = "abc";
t1.Start();
t1.GetType().GetField("m_Name", BindingFlags.Instance | BindingFlags.NonPublic).SetValue(t1, "def");
t1.GetType().GetMethod("InformThreadNameChangeEx", BindingFlags.NonPublic | BindingFlags.Static).Invoke(t1, new object[] { t1, t1.Name});
Run Code Online (Sandbox Code Playgroud)

结果是名称确实已更改,这反映在使用此线程的其他代码上.这样做的背景是我需要记录线程所做的事情以及我使用的日志库(log4net)使用Thread.Name来指定哪个线程执行哪个操作.提前致谢.

编辑:请停止建议明显的事情!如果我问如何重命名它,我知道如何在开始时命名一个线程.

我需要这样做的原因是,线程将被重用,并且它可能被另一个组件使用,我想表示这个,如果有时会发生日志记录,以便有一个特定的线程名称而不是通用数字.

Ste*_*dit 10

操作系统级别的线程没有名称.真的,这只是一个方便的功能.


Bri*_*eon 6

我使用了Reflector的analyze操作,我看到的BCL中唯一的代码(或者更准确地说是Nikolaos看到的)使用Thread.Namegetter的是RegisterClassEx在user32.dll中调用API.在Thread类本身只是指m_Name在成员Namegetter和setter.我怀疑以你采用的方式重命名线程是安全的.除了我将更改您的代码以获取对同一对象的锁定Thread.Name.幸运的是,这不仅仅是Thread实例本身,所以很容易做到.

var t1 = new Thread(TestMethod); 
t1.Name = "abc"; 
t1.Start(); 
lock (t1) 
{
  t1.GetType().
      GetField("m_Name", BindingFlags.Instance | BindingFlags.NonPublic).
      SetValue(t1, "def"); 
  t1.GetType().
      GetMethod("InformThreadNameChangeEx", BindingFlags.NonPublic | 
          BindingFlags.Static).
      Invoke(t1, new object[] { t1, t1.Name});
}
Run Code Online (Sandbox Code Playgroud)

另一件需要注意的事情是,您可能会遇到代码访问安全性和更改私有成员的问题,具体取决于应用程序具有的信任级别.显然,您的测试似乎没有发挥作用,但这里值得一提.