Skip to content

ThreadLocal IsValueCreated Returns True Forever; Even With No Factory #101105

@steevcoco

Description

@steevcoco

Description

Creating a ThreadLocal with no factory; then setting the Value property non-null, will return true from IsValueCreated. Then setting the Value null; it still returns true from IsValueCreated.

The same does happen for an instance with a factory.

Reproduction Steps

using System;
using System.Threading;


public class Program
{
    private static ThreadLocal<object> manual = new();
    private static ThreadLocal<object> factory = new(() => new());


    public static void Main()
    {
        Console.WriteLine("\"Manual\":");
        Console.WriteLine(manual.IsValueCreated); // False
        manual.Value = new();
        Console.WriteLine(manual.IsValueCreated); // True
        manual.Value = null;
        Console.WriteLine(manual.IsValueCreated); // Still true!

        Console.WriteLine();

        Console.WriteLine("\"Factory\":");
        Console.WriteLine(factory.IsValueCreated); // False
        _ = factory.Value;
        Console.WriteLine(factory.IsValueCreated); // True
        factory.Value = null;
        Console.WriteLine(factory.IsValueCreated); // Still true!
    }
}

Expected behavior

When the ThreadLocal is initialized with no factory, and all usage has been by manually setting the Value; it seems inconsistent.

Using a factory, it does seem inconsistent; at least if the documentation does not say "returns true the first time the Value is created; and stays true".

Actual behavior

The way the class is documented, it simply seems that the property should return the current state of the Value all the time.

Regression?

Happens in .net 8 and also net48.

Known Workarounds

Do not use IsValueCreated at all; or otherwise you must set the value once and never change it.

Configuration

No response

Other information

No response

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions