我正在开发一个基于 Asp.net MVC 3.0 并使用 Mono-2.10.8 (Windows 7) 的庞大系统。
直到几天前,一切都很好。
在我的 API 中,我有几个使用字典的实用程序类。例如,像这样一个:
public static class KeyUtility
{
static KeyUtility() {
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);
}
internal static char[] Alphabet;
private static IDictionary<char, byte> ReverseAlphabet;
public static string ToKey(byte[] key, int groupSize)
{
//Accessing Alphabet to generate string key from bytes
}
public static byte[] FromKey(string key)
{
//Accessing ReverseAlphabet to get bytes from string key
}
}
随机我得到这样的异常:
System.IndexOutOfRangeException: Array index is out of range.
at System.Collections.Generic.Dictionary`2<char, byte>.TryGetValue (char,byte&) <0x000a1>
at MyAPI.KeyUtility.FromKey (string) <0x0009a>
at MyApp.Controllers.AboutController.Index () <0x002df>
at (wrapper dynamic-method) object.lambda_method (System.Runtime.CompilerServices.Closure,System.Web.Mvc.ControllerBase,object[]) <0x0002f>
at System.Web.Mvc.ActionMethodDispatcher.Execute (System.Web.Mvc.ControllerBase,object[]) <0x0001b>
at System.Web.Mvc.ReflectedActionDescriptor.Execute (System.Web.Mvc.ControllerContext,System.Collections.Generic.IDictionary`2<string, object>) <0x000ff>
at System.Web.Mvc.ControllerActionInvoker.InvokeActionMethod (System.Web.Mvc.ControllerContext,System.Web.Mvc.ActionDescriptor,System.Collections.Generic.IDictionary`2<string, object>) <0x00019>
at System.Web.Mvc.ControllerActionInvoker/<>c__DisplayClass15.<InvokeActionMethodWithFilters>b__12 () <0x00066>
at System.Web.Mvc.ControllerActionInvoker.InvokeActionMethodFilter (System.Web.Mvc.IActionFilter,System.Web.Mvc.ActionExecutingContext,System.Func`1<System.Web.Mvc.ActionExecutedContext>) <0x000b8>
大多数时候一切都很好并且KeyUtility
工作正常,但在极少数情况下我会遇到这样的异常。尽管它看起来像线程安全问题,但ReverseAlphabet
始终只能以只读方式访问字典,而不能以写入方式访问字典。一旦在静态构造函数中创建它,就只能使用TryGetValue
. 正如我从 MSDN 文章中了解到的那样,在这种情况下它应该是线程安全的。而且,我以前没有见过这个问题。
我应该看什么?我什至无法创建复制品,因为我完全不知道出了什么问题。
Mono-2.10.8 和更早的版本在字典中被证明是稳定的。我已经密集使用它几年了,以前从未见过这种异常。
如何解决这个问题?
升级版:
我记得在麻烦开始的时候,我所做的是将单声道与我的可执行文件静态链接(我将单声道嵌入到我的应用程序中)。我只是下载了单声道的来源。除了我将 libmono 的输出设置为静态库之外,没有任何更改就编译它。我还与 libeay32 和 sqlite3 相关联。所有多线程(MT)。也许这种变化会影响应用程序?不幸的是,我无法在独立单声道下检查这个。在此之前,我正在动态链接所有库,一切都很好。
UPD2: 这里是完整来源的链接:http: //pastebin.com/RU4RNCki