这个问题更多的是关于 C#,而不是关于 log4net(我认为)。
我创建了一个自定义附加程序,并让它读取程序之前设置的静态字段。
令我惊讶的是,静态字段被重新初始化,并且设置值没有进入附加程序。
我启动了 debugview 并看到静态构造函数被调用了两次(!)。这在同一个appdomain中不应该是可能的吧?由于 VS 没有在断点上第二次命中,因此只有 debugview 才能揭示这一点。
请注意,这不是关于避免在 log4net 中使用静态变量的问题。我对 log4net 使用什么样的魔法来完成这个感兴趣?
编辑#1
你好乔恩,大粉丝。
我按照要求进一步隔离了它。首先,我从空白开始,朝着暴露错误的目标情况努力。由于我几乎逐个匹配目标字符并且仍然没有复制,所以我反其道而行之。
从错误情况开始,我删除了所有我认为不重要的东西,直到它开始......按预期工作。
当运行时尝试解析 log4net 程序集时,似乎有一些奇怪的事情发生(在调试模式下观察到)
这是我在调试视图中看到的:
[7756] 常规:警告 - 无法解析模块的“log4net”版本。异常:System.NullReferenceException:对象引用未设置为对象的实例。[7756] 在 DebuggerShared.Services.EventArgs.ModuleLoadedInDebuggerEventArgs..ctor(String modulePath, String moduleLoadMessage, Boolean isUserCode, String name, String version) [7756] General: WARN - Failed to parse module's 'FollowUp.Common' version。异常:System.NullReferenceException:对象引用未设置为对象的实例。[7756] 在 DebuggerShared.Services.EventArgs.ModuleLoadedInDebuggerEventArgs..ctor(字符串 modulePath,字符串 moduleLoadMessage,布尔 isUserCode,字符串名称,字符串版本)
并且 VS 在调试模块屏幕中没有显示路径值。现在我是怎么做到的呢?奇怪的是它设法加载了一个程序集,但不能再告诉从哪里 :)
这是孤立的情况,如果我进一步修改它,它就会开始按预期工作。
https://www.sugarsync.com/pf/D6486369_1701716_00940
我仍然对技术细节感兴趣,但是在删除对 log4net 的引用并再次添加它之后,一切又开始工作了。我很高兴它有效,但它让我烦恼的是我没有一个彻底的解释
此外,静态构造函数现在被调用了两次,这是有道理的,因为当 log4net 得到它时,类型会再次初始化。
我认为在这个问题上花费更多时间是不值得的,因为我认为解决方案处于一种奇怪的状态,并且理解所有这些都具有边际价值。不过,如果你能想到一些东西来解释这一点,我很乐意在这里。
编辑#2
事实证明,某些程序集确实被加载了两次,包括带有静态构造函数的程序集。稍后我将研究这是如何实现的,但我有一个解决方法,即禁用和启用 Costura。Costura 是一项将所有程序集合并为一个的 msbuild 任务。我并不是说 Costura 是根本原因。csproj/sln 文件很容易处于奇怪的状态。
考虑在未来如何更快地诊断这个问题,我启动了 sysinternals ProcessExplorer。现在我希望看到程序集只加载一次,但我发现它们被加载了两次。似乎这是运行时中的一个错误,仅在 .NET 4 中修复
http://forum.sysinternals.com/why-some-net-assemblies-are-duplicated-in-memory_topic15279.html https://connect.microsoft.com/VisualStudio/feedback/details/467560/clr-maps-assemblies -进入虚拟地址空间两次
编辑#3 Costura 使程序集加载了两次。项目所有者在同一天修复了该问题 :) http://code.google.com/p/costura/issues/detail?id=17&thanks=17&ts=1328826304
我们需要一个 Costura 标签,但我没有必要的 1500 声望点。如果您有权利,请创建它。谢谢。
亲切的问候,汤姆