gpt4 book ai didi

c# - .net 标准库在 .net 核心中失败,但在框架中失败

转载 作者:行者123 更新时间:2023-12-03 18:17:08 24 4
gpt4 key购买 nike

我们必须使用来自 3rd 方供应商(perforce)的 api。直到今天,我们能够在 .net 框架应用程序中引用和使用该 API。但是,现在我们正在重构我们的产品,当然我们决定使用新的 .net 环境,即 .net core 2.2。由于 Perforce 没有为 .net 核心发布该库,我们决定将该库移植到 .net 标准。

因此,简而言之,我们下载了源代码,移植并添加为 .net 核心项目中的引用。

到现在为止还挺好。奇怪的是,在使用了该库之后,我们得到了 ExecutionEngineException 来自那个库,它会触发 Environment.Failfast并终止申请。

一个更重要的信息是该库使用另一个 native 库(p4bridge.dll)。

异常(exception)是这样的:

FailFast:
A callback was made on a garbage collected delegate of type 'p4netapi!Perforce.P4.P4CallBacks+LogMessageDelegate::Invoke'.

at Perforce.P4.P4Bridge.RunCommandW(IntPtr, System.String, UInt32, Boolean, IntPtr[], Int32)
at Perforce.P4.P4Bridge.RunCommandW(IntPtr, System.String, UInt32, Boolean, IntPtr[], Int32)
at Perforce.P4.P4Server.RunCommand(System.String, UInt32, Boolean, System.String[], Int32)
at Perforce.P4.P4Command.RunInt(Perforce.P4.StringList)
at Perforce.P4.P4CommandResult..ctor(Perforce.P4.P4Command, Perforce.P4.StringList)
at Perforce.P4.P4Command.Run(Perforce.P4.StringList)
at Perforce.P4.Client.runFileListCmd(System.String, Perforce.P4.Options, System.String, Perforce.P4.FileSpec[])
at Perforce.P4.Client.SyncFiles(System.Collections.Generic.IList`1<Perforce.P4.FileSpec>, Perforce.P4.Options)

我已经知道与 garbage collected delegate 相关的消息.似乎,在某个地方,指向委托(delegate)的指针被传递给非托管库,然后 GC 收集了它。

我们看一下那个 api 的源代码。我们看到了一些可能导致该错误的地方。但是,这只是一个想法。

在调查故障时,我们创建了另一个引用该移植库的 .net 框架应用程序,以及 那么我们在.net框架中没有遇到任何错误。

我的问题是:
  • .net framework 和.net core 在垃圾回收机制方面有什么区别 ?
  • .net 框架和 .net 核心如何以不同的方式对同一个库使用react?
  • 最佳答案

    我想发布我的问题的答案,因为我已经解决了这个问题。当您现在阅读我的答案时,这意味着您遇到了类似的问题。首先感谢@MarcGravell他的评论,并建议您阅读评论。

    首先,想总结一下第二个问题的答案:

    How is that possible that, .net framework and .net core reacts to the same library in a different ways?



    老实说,乍一看,我认为 .net 标准库在任何地方都会以相同的方式表现自己。但是,我当然错了。

    让我们从 .Net Standard 的“定义”开始. .NET Standard只不过是 规范(将其视为接口(interface)) ,它只是根据版本声明特定平台公开了哪些类型和 API。

    如果您看一下,您会发现您的标准库引用了包含 netstandard.dll 的 .NET Standard SDK。包含 API,或者更确切地说,是 契约(Contract) ,我们可以在库项目中使用。如果您愿意看一下,请使用 Ildasm.exe 访问您的标准库,你会看到它正在使用 .netstandard.dll .

    enter image description here

    让我们检查一下我们的核心和框架应用程序是如何使用它的。并且在核心上它比框架更好。

    我一直是图表的粉丝:

    enter image description here

    正如您在图中看到的,核心和框架应用程序都引用了 自己的 netstandard.dll .这些库是基于 type forwarding 构建的。概念。
    对于核心应用程序, BCL类型由 System.Runtime.dll 提供, 而对于框架应用程序 BCL类型由 mscorlib.dll 提供.所以, 两种不同的实现 .

    例如,这里是 .netstandard 的 IL 代码核心应用程序将使用的库:

    enter image description here

    阅读更多关于 type forwarding from msdn .

    Source关于 .NET Standard 的详细信息.

    现在谈谈我的第一个问题:

    Is there any difference between .net framework and .net core in terms of garbage collector mechanism?



    其实微软不断进化GC机制也不足为奇。

    现在我如何解决这个问题:

    好消息是我移植到标准的那个库是开源的。我调查了这个问题,简而言之,他们将委托(delegate)指针传递给非托管库。并且该非托管库保存指针并尝试在某个生命周期内使用它,该生命周期比该指针的生命周期长。实际上,有趣的一点是框架 GC 没有以某种方式收集该委托(delegate),这就是为什么框架方面没有异常(exception)。但是,在核心 GC 收集该委托(delegate)并为失败创建原因的情况下。我确实改变了设置该字段的方式,现在它可以工作了。我将该字段声明为静态并在静态构造函数中对其进行初始化,因此该委托(delegate)的生命周期与应用程序生命周期一样长。

    关于c# - .net 标准库在 .net 核心中失败,但在框架中失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59301230/

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