Загадочное поведение Dictionary

Я работаю над огромной системой, основанной на 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 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.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) <0x000ff>
at System.Web.Mvc.ControllerActionInvoker.InvokeActionMethod (System.Web.Mvc.ControllerContext,System.Web.Mvc.ActionDescriptor,System.Collections.Generic.IDictionary`2) <0x00019>
at System.Web.Mvc.ControllerActionInvoker/<>c__DisplayClass15.b__12 () <0x00066>
at System.Web.Mvc.ControllerActionInvoker.InvokeActionMethodFilter (System.Web.Mvc.IActionFilter,System.Web.Mvc.ActionExecutingContext,System.Func`1) <0x000b8>

Большую часть времени все нормально и KeyUtilityработает правильно, но в редких случаях я получаю такое исключение. Несмотря на то, что это выглядит как проблема безопасности потоков, словарь ReverseAlphabetвсегда доступен только для чтения и никогда для записи. После создания в статическом конструкторе к нему можно получить доступ только с помощью TryGetValue. Насколько я понимаю из статьи MSDN, в этом случае он должен быть потокобезопасным. Более того, я не видел этой проблемы раньше.

На что мне смотреть? Я даже не могу создать репродукцию, так как совершенно не понимаю, что не так.

Mono-2.10.8 и более ранние версии оказались стабильными со словарями. Я активно использую его в течение нескольких лет и никогда раньше не видел такого исключения.

Как это исправить?

UPD:

Вспомнил, что незадолго до начала траблов то, что я сделал, это статически слинковал моно с моим исполняемым файлом (встраиваю моно в свое приложение). Я просто скачал исходники моно.Скомпилировал его без каких-либо изменений, за исключением того, что я настроил вывод libmono в статическую библиотеку. Я также связался с libeay32 и sqlite3. Все многопоточные (MT). Может быть, это изменение может повлиять на приложение? К сожалению, я не могу проверить это в автономном моно. До этого я динамически связывал все библиотеки, и все было в порядке.

UPD2: Вот ссылка на полные исходники: http://pastebin.com/RU4RNCki

8
задан LukeH 23 May 2012 в 11:09
поделиться