Open koenigst opened 6 months ago
Tagging subscribers to this area: @dotnet/area-system-reflection See info in area-owners.md if you want to be subscribed.
Author: | koenigst |
---|---|
Assignees: | - |
Labels: | `area-System.Reflection` |
Milestone: | - |
I assume Equal()
is equivalent to ReferenceEquals()
in this case.
As far as I can see yes. ParameterInfo
and RuntimeParameterInfo
inherit their equality implementation from object
. I think this is frequently the case with System.Reflection
classes.
Description
If multiple threads call
System.Reflection.MethodBase.GetParameters()
at the same time, the resultingParameterInfo
s are not alwaysEquals
even though they represent the same parameter.Reproduction Steps
Expected behavior
Sequential and concurrent access should behave the same.
Actual behavior
The concurrent test sometimes fails (repeat test run a few times as the concurrency issue can not be reproduced reliably). The likely cause is that multiple threads fill the
RuntimeMethodInfo.m_parameters
cache resulting in multiple instances ofParameterInfo
for the same method parameter. Most information on the instances are identical but becauseParameterInfo.Equals
is based on reference equality the test fails.Regression?
The code is essentially the same as in .NET Framework 4.8.1 and the relevant .NET Core code has not changed in the last five years.
Known Workarounds
Call
MethodBase.GetParameters
from a single thread before accessing it in parallel. Once the cache is initialised all further concurrent calls will return the correct parameter instances.Configuration
Other information
Calling reflection code concurrently seems to be a rather unusual case because most of the reflection code uses the same not completely thread-safe caching mechanism and I have not run into this issue in the last ten years of .NET use. I am also aware that making the caching thread-safe has some overhead that is not desired for dealing with a rare occurence. The documentation declares the class as thread-safe. Would it make sense to change the documentation instead of the implementation?