gpt4 book ai didi

c# - 静态构造函数在同一个appdomain中被调用两次?

转载 作者:太空狗 更新时间:2023-10-29 23:17:07 24 4
gpt4 key购买 nike

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

最佳答案

看起来您设法加载了 log4net 的两个单独实例进入同一个AppDomain .

一项目引用:

<Reference Include="log4net">
<HintPath>..\packages\log4net.1.2.11\lib\net35-full\log4net.dll</HintPath>
</Reference>

另一个:
<Reference Include="log4net, Version=1.2.10.0, Culture=neutral, PublicKeyToken=1b44e1d426115821, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\ExternalReferences\log4net.dll</HintPath>
</Reference>

其中一个是强命名的,另一个不是,这导致 .net 赋予它们不同的身份。提示路径也不同。还有一个似乎是 1.2.10 , 其他 1.2.11 .

尝试调用 AppDomain.GetAssemblies()并检查 log4net出现两次。

关于c# - 静态构造函数在同一个appdomain中被调用两次?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9192451/

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