【发布时间】:2010-07-28 13:34:02
【问题描述】:
在 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);
}
}
}
鉴于 Java 允许重命名线程,并且使用的大多数底层线程结构在两个平台上都是由操作系统提供的,我倾向于认为我实际上可以在 C# 中重命名一个线程,如果我避免使用某组a) 我不在乎或 b) 根本不使用的功能。
你知道为什么线程重命名是一次写入操作吗?知道更改名称是否会破坏某些内容吗?
我尝试了一个测试,我将线程重命名为:
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});
结果是名称确实发生了变化,这反映在使用该线程的其他代码上。这样做的背景是我需要记录线程所做的事情,而我使用的日志库(log4net)使用 Thread.Name 来指定哪个线程执行什么操作。提前致谢。
编辑:请停止建议明显的事情!如果我问如何重新命名线程,我知道如何在开始时命名线程。
我需要这样做的原因是线程将被重新使用,并且它可能被另一个组件使用,我想表明这一点,如果以及何时会发生日志记录,以便有一个特定的线程名称,而不是通用编号。
【问题讨论】:
-
为什么要重命名线程?不是因为Java可以做到吗?
-
@ChrisF:请参阅上面的编辑。
-
很公平,尽管您可以从
Thread派生一个LoggingThread,它公开一个名为ThreadName的读/写属性并使用它来代替。我知道这是一个具有相同值的额外属性,但它可以满足您的需求,并且不依赖可能会中断的反射。 -
@Chris:线程是一个密封类,所以我不能使用继承来覆盖名称。此外,正如我上面提到的,log4net 使用 Thread.Name,所以我也不能使用组合,如引入 ThreadName 属性,因为它永远不会被 log4net 读取。
-
积分。在发布这样的 cmets 之前,我应该仔细检查。干得好,我没有把它作为答案发布;)
标签: c# .net multithreading