Reputation: 13838
In my app, I want to name the thread performed by a task using a name relevant to that task, so I can keep the the threads straight. So I use code like
Threading.Thread.CurrentThread.Name = this.GetType().Name;
where this
is a class that's dedicated to that task, like class FilePurgeTask {...}
The problem is that a thread can be reused with a different class in scope, so the name would then be wrong. And if I try to reset the name, it fails with System.InvalidOperationException ...This property has already been set and cannot be modified
Indeed, the docs say "This property is write-once.".
Is there any way to work around it?
Upvotes: 1
Views: 346
Reputation: 17185
The documentation is outdated.
This limitation was removed in .NET 6.0, but apparently the documentation has not been updated. In .NET 5.0, the Name
property is implemented as:
public string? Name
{
get => _name;
set
{
lock (this)
{
if (_name != null)
{
throw new InvalidOperationException(SR.InvalidOperation_WriteOnce);
}
_name = value;
ThreadNameChanged(value);
}
}
}
while in .NET 6.0, this is simply changed to:
public string? Name
{
get => _name;
set
{
lock (this)
{
if (_name != value)
{
_name = value;
ThreadNameChanged(value);
_mayNeedResetForThreadPool = true;
}
}
}
}
This simple test works fine when running under .NET 6.0, and the debugger correctly displays changing thread names when single-stepping:
[Fact]
public void NameThread()
{
Thread.CurrentThread.Name = "Blah";
Thread.CurrentThread.Name = "Fasel";
}
So, the "workaround" is to upgrade to .NET 6.0 ;-)
Upvotes: 1
Reputation: 1629
You could use a thread-safe ConcurrentDictionary to store the thread ID (key) and the operation it is performing (value). Using the Thread.Name property won't support the dynamical, reassignable tagging you are looking for.
For what it's worth, the Name property will be null unless it has been set, so you could simply wrap your code in a null check like so to avoid throwing an exception:
if(Thread.CurrentThread.Name == null)
{
Thread.CurrentThread.Name = this.GetType().Name;
}
Upvotes: 0