简体   繁体   English

如何修复 Windows-API-Code-Pack 中的 ArgumentException?

[英]How to fix ArgumentException in Windows-API-Code-Pack?

I've created an application that reads properties from files using the Windows-API-Code-Pack from this package.我创建了一个应用程序,该应用程序使用包中的 Windows-API-Code-Pack 从文件中读取属性。 I'm having an issue when retrieving properties我在检索属性时遇到问题

var width = fileInfo.Properties.GetProperty(SystemProperties.System.Video.FrameWidth).ValueAsObject;

The code breaks here giving me代码在这里中断给我

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)

This happens mostly when calling this portion of a code in a PLINQ这主要发生在在 PLINQ 中调用这部分代码时

.AsParallel().WithDegreeOfParallelism(_maxConcurrentThreads).ForAll(...)

even if the degree is set to 1. How can I solve it?即使度数设置为1。我该如何解决?

To extend on your existing answer, switching the Dictionary to a ConcurrentDictionary would also solve the problem and remove the need for locks.为了扩展您现有的答案,将 Dictionary 切换到 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);
    }

Following stuartd suggestion I was able to solve this issue by modifying the source code of the package and adding locks in this code at lines 57 and 62, like this按照stuartd 的建议,我能够通过修改包的源代码并在第 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);
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM