dotnet / dotnet-api-docs

.NET API reference documentation (.NET 5+, .NET Core, .NET Framework)
https://docs.microsoft.com/dotnet/api/
Other
688 stars 1.52k forks source link

Examples output is incorrect #9629

Open ChuckEQX opened 5 months ago

ChuckEQX commented 5 months ago

The Example out is reverse order of what it normally is. Actually, both outputs are acceptable since the thread scheduler could cause a race condition, as the example output displays, switching to the second worker thread before the first even though the first thread's Task.Delay(100) should complete before the second.

Documented output: // Exiting AsyncMethodB. // Expected 'Value 2', got 'Value 2', ThreadLocal value is '' // Exiting AsyncMethodB. // Expected 'Value 1', got 'Value 1', ThreadLocal value is ''

Actual Output: // Exiting AsyncMethodB. // Expected 'Value 1', got 'Value 1', ThreadLocal value is '' // Exiting AsyncMethodB. // Expected 'Value 2', got 'Value 2', ThreadLocal value is ''

Additional explanation of why the ThreadLocal value is unset would also be useful. Showing an equivalent decomposition showing the thread spawning abstraction:

static async Task AsyncMethodB(string expectedValue)
{
    Console.WriteLine("Entering AsyncMethodB.");
    Console.WriteLine("   Expected '{0}', AsyncLocal value is '{1}', ThreadLocal value is '{2}'",
                      expectedValue, _asyncLocalString.Value, _threadLocalString.Value);
    await Task.Run(()=>
    {
        Task.Delay(100).Wait();
        Console.WriteLine("Exiting AsyncMethodB.");
        Console.WriteLine("   Expected '{0}', got '{1}', ThreadLocal value is '{2}'",
                      expectedValue, _asyncLocalString.Value, _threadLocalString.Value);
    }    
}

Then stating the reason ThreadLocal is empty is because : "The _threadLocalString.Value is being accessed from a new ThreadPool worker thread and the Value has not been set in this thread."

MihaZupan commented 5 months ago

The example in question: https://learn.microsoft.com/dotnet/api/system.threading.asynclocal-1#examples