dotnet/runtime
在 GitHub 查看ConfigurationManager.AppSettings getter is not thread safe and multiple instances are created
Open
#56,075 建立於 2021年7月21日
area-System.Configurationhelp wanted
倉庫指標
- Star
- (17,886 star)
- PR 合併指標
- (平均合併 12天 11小時) (30 天內合併 661 個 PR)
描述
Description
ConfigurationManager.AppSettings getter should return a single, cached instance.
The official documentation:
The ConfigurationManager class includes members that enable you to perform the following tasks:
- Read a section from a configuration file. To access configuration information, call the GetSection method. For some sections such as appSettings and connectionStrings, use the AppSettings and ConnectionStrings classes. These members perform read-only operations, use a single cached instance of the configuration, and are multithread aware. The actual behavior is different. If the
AppSettingscached instance is not yet initialized and property is accessed concurrently, it can return multiple different instances.
Code to reproduce the issue:
var tasks = Enumerable.Range(1, 100)
.Select(_ => Task.Run(() => ConfigurationManager.AppSettings))
.ToList();
var settings = await Task.WhenAll(tasks);
var instances = settings.Distinct().ToList();
Console.WriteLine($"{instances.Count} AppSettings were created!");
if (instances.Count > 1)
{
instances[0]["key"] = "value";
if (instances.Any(appSettings => appSettings["key"] != "value"))
{
Console.WriteLine("A key set on one instance doesn't affect other created instances");
}
}
Output on my workstation with 4 core CPU:
4 AppSettings were created!
Key set on one instance doesn't affect other created instances
Configuration
- runtime: 5.0.302
- nuget:
System.Configuration.ConfigurationManager 5.0.0 - OS: Windows / Linux
- arch: x64
Regression?
No - the same issue can be reproduced on .NET 4.8 referencing the System.Configuration assembly
Other information
The code in the ConfigurationManager class is probably correct. I suspect the ClientConfigurationSystem class or some internals deeper.