螺纹重命名 [英] Thread Renaming

查看:139
本文介绍了螺纹重命名的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在Java中,重命名线程是可能的。在.NET事实并非如此。这是因为该名称是一个属性,它是一次性写入的Thread类:

In Java, renaming threads is possible. In .NET it is not. This is because the Name is a property that is write-once in the Thread class:

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);
        }
    }
}

鉴于Java允许线程重命名和最常用的底层线程结构是操作系统提供的在这两个平台上,我倾向于认为,我居然可以重命名在C#中的线程,如果我避免某一组功能是:a)我不关心或b)不使用的。

Given the fact that Java allows thread renaming and most of the underlying thread structures used are OS-supplied in both platforms, I'm inclined to think that I could actually rename a thread in C#, if I avoid a certain set of functionality that a) I don't care or b) don't use at all.

你有任何想法,为什么线程改名为一次写入操作?如果更改名称打破东西你知道吗?

Do you have any idea why Thread renaming is a write-once operation? Any idea if changing the name breaks something?

我已经尝试了测试,我重新命名线程这样:

I have tried a test where I rename the thread as such:

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});

其结果是,该名称确实变,这是在使用该线程其他code反射。背景情况是,我需要记录的事情,做线程和日志库我使用(log4net的)使用Thread.Name指定哪个线程做什么动作。先谢谢了。

The result is that the name is indeed changed and this is reflected on other code that uses this thread. The background to this is that I need to log things that threads do and the logging library I use (log4net) uses Thread.Name to specify which thread does what action. Thanks in advance.

编辑:请停止提示明摆着的事!我知道如何,如果我是问如何重新命名命名线程的开始。

Please stop suggesting obvious things! I know how to name a thread at start if I am asking how to RE-name it.

我之所以需要这样做,是该线程将被重新使用,并且可以使用由另一个组件和欲表示这一点,如果当有将要登录发生的历史,以便具有一个特定线程名称,而不是一个通用的数目

The reason why I need to do this, is that the thread will be re-used and it may be used by another component and I want to signify this, if and when there will be logging occuring, so as to have a specific thread name, rather than a generic number.

推荐答案

我用的分析,从操作的反光和唯一的code BCL中,我看到(或以上precisely尼可拉斯看到),它使用了 Thread.Name 吸气剂调用user32.dll中的 RegisterClassEx API。该类本身只是指 m_Name 成员在名称 getter和setter。我怀疑它是安全重命名线程,你都采用的方式。除我会改变你的code,以获得相同对象的锁 Thread.Name 将有。幸运的是没有比发其他实例本身,所以很容易做到的。

I used the analyze operation from Reflector and the only code in the BCL that I saw (or more precisely Nikolaos saw) which uses the Thread.Name getter was a call to the RegisterClassEx API in user32.dll. The Thread class itself only refers to the m_Name member in the Name getter and setter. I suspect it is safe to rename the thread in the manner you have adopted. Except that I would change your code to acquire a lock on the same object that Thread.Name would have. Fortunately that is none other than the Thread instance itself so it is easy to do.

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});
}

另外要注意的是,你可能有问题,code访问安全性和不断变化的根据是什么信任级别的应用程序具有私有成员。显然,这似乎并没有发挥作用与你的测试,但这里值得一提。

Another thing to note is that you might have problems with code access security and changing private members depending on what trust level the application has. Obviously that did not seem to come into play with your test, but it is worth mentioning here.

这篇关于螺纹重命名的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆