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);
}
}
}
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});
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.
EDIT: 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.
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.Namegetter was a call to theRegisterClassExAPI in user32.dll. TheThreadclass itself only refers to them_Namemember in theNamegetter 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 thatThread.Namewould have. Fortunately that is none other than theThreadinstance itself so it is easy to do.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.