Description
TypeDescriptor.GetConverter(type)
returns different results when calling on multiple threads with the same type and this type
has a custom TypeDescriptionProvider
.
This issue is reproducible with target frameworks netcoreapp2.2
and net472
on window 10 x64.
Repro
I'm calling the method on 10 threads and print the fetched type converter at the end.
Expected output
All 10 calls return MyTypeConverter
Actual output
The method return both TypeConverter
and MyTypeConverter
in random order like the following:
TypeConverter
TypeConverter
TypeConverter
MyTypeConverter
TypeConverter
TypeConverter
TypeConverter
TypeConverter
TypeConverter
TypeConverter
The good thing is that the method is returning MyTypeConverter
after the concurrent calls are finished. The bad thing is that there are libs (like newtonsoft.json) that are caching the type descriptors. If the cache of 3rd party lib is initialized with wrong descriptor then the application is broken until restart.
Program.cs
public class Program
{
public static async Task Main()
{
var tasks = new Task<TypeConverter>[10];
for (var i = 0; i < tasks.Length; i++)
{
tasks[i] = new Task<TypeConverter>(() => TypeDescriptor.GetConverter(typeof(MyClass)));
}
foreach (var t in tasks)
{
t.Start();
}
foreach (var conv in await Task.WhenAll(tasks))
{
Console.WriteLine(conv.GetType().Name);
}
}
}
[TypeDescriptionProvider(typeof(MyClassTypeDescriptionProvider))]
public class MyClass
{
}
public class MyClassTypeDescriptionProvider : TypeDescriptionProvider
{
public override ICustomTypeDescriptor GetTypeDescriptor(Type objectType, object instance)
{
return new MyClassTypeDescriptor();
}
}
public class MyClassTypeDescriptor : CustomTypeDescriptor
{
public override TypeConverter GetConverter()
{
return new MyTypeConverter();
}
}
public class MyTypeConverter : TypeConverter
{
}
.csproj-file
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netcoreapp2.2</TargetFramework>
<OutputType>EXE</OutputType>
</PropertyGroup>
</Project>