前言:我正在努力将库迁移到并行处理数据,并且PropertyDescriptor.GetValue()
上的线程之间存在85%以上的争用,从而在多个核心上进行并行处理与处理单个核心相同,有时甚至更糟。
问题:
当调用TypeDescriptor.GetProperties(Type)
时,它似乎返回对相同PropertyDescriptorCollection
的相同引用,它对所有相同的PropertyDescriptor
对象具有相同的引用。这是有问题的,因为我需要为每个线程设置新的PropertyDescriptor
集。共享相同的资源会导致线程不断相互阻塞。
粗略示例:
public static void Test()
{
var class1 = new ExampleClass();
var class2 = new ExampleClass();
var test1 = TypeDescriptor.GetProperties(typeof(ExampleClass));
var test2 = TypeDescriptor.GetProperties(typeof(ExampleClass));
Console.WriteLine(Object.ReferenceEquals(test1, test2));
int i = 0;
foreach(PropertyDescriptor item in test1)
{
Console.WriteLine(Object.ReferenceEquals(test1[i], test2[i]));
i++;
}
}
在这种情况下,每个Object.ReferenceEquals都将返回true。显示它们都指向相同的对象,并且不是不同的。当多个线程在同一GetValue()
对象上调用PropertyDescriptor
时,这会导致严重的性能问题。
如何为每个对象属性获取全新的PropertyDescriptor
个对象?
注意: PropertyInfo
通过myType.GetProperties()
检索到同样的问题。它返回的PropertyInfo
引用相同的对象,所以即使是执行缓存。
其他信息/调查结果:
PropertyInfo
内。因此,获取和调用该方法是不可并行化的,因为它将依赖于所有线程的相同MethodInfo实例。PropertyDescriptor
ReflectPropertyDescriptor
}在GetValue()
期间经历的过程使用Type.GetProperty()
(RunTimeType.GetProperty()
),它使用属性信息缓存返回结果。
PropertyDescriptor
和PropertyInfo
似乎使用相同的共享缓存来返回属性信息实例,它们都用于访问属性getter方法(也是缓存的)。TL; DR:它一直缓存。