当前位置: 首页 > 编程语言 > C#

词典分享的神秘行为

时间:2023-04-10 13:38:14 C#

Dictionary的神秘行为我正在开发一个基于Asp.netMVC3.0并使用Mono-2.10.8(Windows7)的庞大系统。一切都很好,直到几天前。在我的API中,我有几个使用字典的实用程序类。例如,像这样:publicstaticclassKeyUtility{staticKeyUtility(){Alphabet=new[]{'A','B','C','D','E','F','G','H'、'J'、'K'、'L'、'M'、'N'、'P'、'R'、'S'、'T'、'U'、'V'、'X','Y','Z','0','1','2','3','4','5','6','7','8','9'};ReverseAlphabet=Alphabet.Select((c,i)=>new{Char=c,Value=i}).ToDictionary(k=>k.Char,v=>(byte)v.Value);}内部静态char[]字母表;私有静态IDictionaryReverseAlphabet;publicstaticstringToKey(byte[]key,intgroupSize){//访问Alphabet从字节生成字符串key}publicstaticbyte[]FromKey(stringkey){//访问ReverseAlphabet从字符串key获取字节}}随机我得到这样的例子:System.IndexOutOfRangeException:数组索引超出范围。在System.Collections.Generic.Dictionary`2.TryGetValue(char,byte&)在MyAPI.KeyUtility.FromKey(string)在MyApp.Controllers.AboutController.Index()在(wrapperdynamic-method)object.lambda_method(System.Runtime.CompilerServices.Closure,System.Web.Mvc.ControllerBase,object[])在System.Web.Mvc.ActionMethodDispatcher.Execute(System.Web.Mvc.ControllerBase,object[])在System.Web.Mvc。ReflectedActionDescriptor.Execute(System.Web.Mvc.ControllerContext,System.Collections.Generic.IDictionary`2)在System.Web.Mvc.ControllerActionInvoker.InvokeActionMethod(System.Web.Mvc.ControllerContext,System.Web.Mvc.ActionDescriptor,System.Collections.Generic.IDictionary`2)在System.Web.Mvc.ControllerActionInvoker/c__DisplayClass15.b__12()在System.Web.Mvc.ControllerActionInvoker.InvokeActionMethodFilterSystem.Func`1)大多数时候一切都很好,KeyUtility工作正常,但在极少数情况下我会遇到这样的异常虽然它看起来像线程安全问题,但字典ReverseAlphabet始终只用于读取而不用于写入。一旦在静态构造函数中创建,就只能通过TryGetValue访问它。据我从MSDN文章中了解到,它应该是线程安全的。另外,我以前没见过这个问题。我应该怎么看?我什至无法复制,因为我完全不知道哪里出了问题。事实证明Mono-2.10.8及更早版本的词典是稳定的。我已经密集使用了几年,以前从未见过这个异常。如何解决这个问题呢?UPD:我记得,当问题开始时,我所做的是将单声道静态链接到我的可执行文件(我将单声道嵌入我的应用程序中)。我刚刚下载了单声道的源代码。除了我将libmono的输出设置为静态库外,它无需任何更改即可编译。我还链接了libeay32和sqlite3。所有多线程(MT)。也许此更改会影响应用程序?不幸的是,我无法在独立的单声道中检查它。在此之前,我动态链接了所有库,一切都很好。UPD2:这是完整资源的链接:http://pastebin.com/RU4RNCki我所做的是静态链接单声道与我的可执行文件你已经知道我认为的问题,肯定会破坏单声道。静态链接时不再发生的最重要的事情是,只要新线程开始在进程中执行,Windows就会生成DllMain()回调。这就是CLR了解可能执行托管代码的线程的方式。静态构造函数确实是一种可能的失败模式,必须阻止线程执行类中的任何代码,直到cctor()完成执行。如果CLR不知道线程,它就不能这样做。如果你想让它工作,那么你至少需要在你自己的DllMain()函数中提供一个替代mono_thread_info_attach()调用的方法。总的来说,我认为这是一个太多的优化。以上就是C#学习教程:Dictionary的神秘行为分享的全部内容。如果对你有用,需要进一步了解C#学习教程,希望大家多多关注。本文收集自网络,不代表立场。如涉及侵权,请点击右侧联系管理员删除。如需转载请注明出处: