gpt4 book ai didi

c# - Dictionary 的神秘行为

转载 作者:太空狗 更新时间:2023-10-29 18:23:04 26 4
gpt4 key购买 nike

我正在开发一个基于 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 和更早的版本与字典一起使用时是稳定的。我已经密集使用它几年了,以前从未见过这种异常。

如何解决这个问题?

更新:

我记得在问题刚开始出现时,我所做的就是将 mono 与我的可执行文件静态链接(我将 mono 嵌入到我的应用程序中)。我只是下载了单声道的源代码。编译它没有任何更改,除了我将 libmono 的输出设置为静态库。我还链接了 libeay32 和 sqlite3。全是多线程(MT)。也许此更改会影响应用程序?不幸的是我不能在独立的单声道下检查这个。在此之前,我动态链接所有库,一切正常。

UPD2:这是完整资源的链接:http://pastebin.com/RU4RNCki

最佳答案

what i've done is statically linked mono with my executable

您已经知道我认为的问题,那肯定会破坏单声道。静态链接时不再发生的最重要的事情是 DllMain() 回调,每当新线程开始在进程中执行时,Windows 都会进行回调。这就是 CLR 了解可能执行托管代码的线程的方式。静态构造函数确实是一种可能的失败模式,必须阻止线程执行类中的任何代码,直到 cctor() 完成执行。如果 CLR 不知道线程,则它无法执行此操作。

如果您想完成这项工作,那么您至少需要为您自己的 DllMain() 函数中的 mono_thread_info_attach() 调用提供替代方法。总的来说,我会说这是一个太多的优化。

关于c# - Dictionary<TKey, TSource> 的神秘行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10717406/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com