C#学习教程:调用MethodInfo.MakeGenericMethod时,此键错误是什么意思?分享


调用MethodInfo.MakeGenericMethod时,此键错误是什么意思?

今天我从一些旧的动态转换代码中得到了这个错误(我已经改变了最后一行并省略了堆栈跟踪的其余部分):

Item has already been added. Key in dictionary: 'Int32 Count[Object](System.Collections.Generic.IEnumerable`1[System.Object])' Key being added: 'Int32 Count[Object](System.Collections.Generic.IEnumerable`1[System.Object])' ---> System.ArgumentException: Item has already been added. Key in dictionary: 'Int32 Count[Object](System.Collections.Generic.IEnumerable`1[System.Object])' Key being added: 'Int32 Count[Object](System.Collections.Generic.IEnumerable`1[System.Object])' at System.Reflection.CerHashtable`2.Insert(K[] keys, V[] values, Int32& count, K key, V value) at System.Reflection.CerHashtable`2.Preallocate(Int32 count) at System.RuntimeType.RuntimeTypeCache.GetGenericMethodInfo(RuntimeMethodHandle genericMethod) at System.RuntimeType.GetMethodBase(RuntimeTypeHandle reflectedTypeHandle, RuntimeMethodHandle methodHandle) at System.Reflection.RuntimeMethodInfo.MakeGenericMethod(Type[] methodInstantiation) at MyNamespace.CommunicationExtensions.BuildMessage[T](T obj) 

全class

 public static class CommunicationExtensions { static readonly object lockobj = new object(); public static bool CanBuildMessage(this T obj) where T: class { return obj != null && (MessageFactory.MessageBuilders.ContainsKey(obj.GetType())); } public static string BuildMessage(this T obj) { lock (lockobj) { Delegate d; var type = obj.GetType(); if (MessageFactory.MessageBuilders.TryGetValue(type, out d)) { var castMethod = typeof(CommunicationExtensions).GetMethod("Cast").MakeGenericMethod(type); var castedObject = castMethod.Invoke(null, new object[] { obj }); return d.DynamicInvoke(castedObject) as string; } } return null; } public static T Cast(object o) { return (T)o; } } 

MessageFactory.MessageBuilders是一个Dictionary<Type,Func>包含编译的lambda表达式,这些表达式根据需要延迟构建,以将Message事件(基于EventArgs的简单自动属性类)转换为其他系统中使用的字符串格式。 我认为这不重要。 我认为导致此问题的唯一代码是:

 public static class CastError{ public static void GetCast(this T obj) { var type = obj.GetType(); var castMethod = typeof(CastError).GetMethod("Cast").MakeGenericMethod(type); //... } public static T Cast(object o) { return (T)o; } } 

它看起来像是框架中的失败,无法正确锁定MakeGenericMethod的内部。

当调用MakeGenericMethod时,框架应该使用指定的generics参数创建方法的新版本,或者如果在创建该generics方法之前使用了相同的generics参数类型,那么它应该返回先前的 – 生成方法。 看起来你遇到了一个边缘情况,在多个线程上调用MakeGenericMethod可能导致竞争条件,其中两个线程都认为该方法尚未生成并继续生成它,然后随后冲突存储生成的方法以供将来调用。

也就是说,在这种情况下,看起来它都处于锁定状态,所以我并不完全相信这也是问题所在。

我将它与MSFT一起提交为一个bug,除非其他人可以解释这是预期的行为。

上述就是C#学习教程:调用MethodInfo.MakeGenericMethod时,此键错误是什么意思?分享的全部内容,如果对大家有所用处且需要了解更多关于C#学习教程,希望大家多多关注—猴子技术宅(www.ssfiction.com)

本文来自网络收集,不代表猴子技术宅立场,如涉及侵权请点击右边联系管理员删除。

如若转载,请注明出处:https://www.ssfiction.com/ckf/1269732.html

(0)
上一篇 1天前
下一篇 1天前

精彩推荐

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注