私は、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