我已经创建了一个应用程序,它使用this包中的Windows Code-Pack从文件中读取属性。我在检索属性时遇到问题
var width = fileInfo.Properties.GetProperty(SystemProperties.System.Video.FrameWidth).ValueAsObject;代码在这里中断,它给了我
System.ArgumentException: An item with the same key has already been added.
at System.ThrowHelper.ThrowArgumentException(ExceptionResource resource)
at System.Collections.Generic.Dictionary`2.Insert(TKey key, TValue value, Boolean add)
at Microsoft.WindowsAPICodePack.Shell.PropertySystem.ShellPropertyFactory.GenericCreateShellProperty[T](PropertyKey propKey, T thirdArg)
at Microsoft.WindowsAPICodePack.Shell.PropertySystem.ShellProperties.GetProperty(PropertyKey key)这主要发生在调用PLINQ中的这部分代码时
.AsParallel().WithDegreeOfParallelism(_maxConcurrentThreads).ForAll(...)即使度数设置为1。我如何解决它?
发布于 2019-04-12 16:31:58
为了扩展您现有的答案,将字典切换到ConcurrentDictionary也可以解决这个问题,并消除对锁的需求。
private static ConcurrentDictionary<int, Func<PropertyKey, ShellPropertyDescription, object, IShellProperty>> _storeCache
= new ConcurrentDictionary<int, Func<PropertyKey, ShellPropertyDescription, object, IShellProperty>>();
...
private static IShellProperty GenericCreateShellProperty<T>(PropertyKey propKey, T thirdArg)
{
...
Func<PropertyKey, ShellPropertyDescription, object, IShellProperty> ctor;
ctor = _storeCache.GetOrAdd((hash, (key, args) -> {
Type[] argTypes = { typeof(PropertyKey), typeof(ShellPropertyDescription), args.thirdType };
return ExpressConstructor(args.type, argTypes);
}, {thirdType, type});
return ctor(propKey, propDesc, thirdArg);
}发布于 2019-04-12 15:57:03
按照stuartd的建议,我能够通过修改包的源代码并在this code的第57和62行添加锁来解决这个问题,如下所示
lock (_storeCache)
{
if (!_storeCache.TryGetValue(hash, out ctor))
{
Type[] argTypes = { typeof(PropertyKey), typeof(ShellPropertyDescription), thirdType };
ctor = ExpressConstructor(type, argTypes);
lock (_storeCache)
_storeCache.Add(hash, ctor);
}
}https://stackoverflow.com/questions/55635429
复制相似问题