我们需要使用第三方供应商(perforce)的API。直到今天,我们能够在.net框架应用程序中引用和使用该API。但是,现在我们正在重构我们的产品,并且当然决定使用新的.net环境,即.net core 2.2。由于Perforce没有为.net core发布该库,因此我们决定将该库移植到.net standard。
简而言之,我们下载了源代码,进行了移植,并将其添加为.net core项目的引用。
到目前为止,一切都很好。奇怪的是,在使用该库后,我们从该库得到
还有一个重要信息,该库使用另一个本地库(p4bridge.dll)。
异常如下:
我已经了解与“垃圾回收委托”相关的消息。似乎在某些地方将委托指针传递给非托管库,然后GC将其回收。
我们查看了该API的源代码。我们看到了一些可能导致该错误的原因。但是这只是一个想法。
在调查故障时,我们创建了另一个引用了该移植库的.net框架应用程序,然后我们没有遇到任何.net框架中的错误。
我的问题是:
1. .net框架和.net core在垃圾收集机制方面有什么区别吗? 2. 怎么可能,.net框架和.net core以不同的方式响应相同的库?
简而言之,我们下载了源代码,进行了移植,并将其添加为.net core项目的引用。
到目前为止,一切都很好。奇怪的是,在使用该库后,我们从该库得到
ExecutionEngineException
,它会触发Environment.Failfast
并终止应用程序。还有一个重要信息,该库使用另一个本地库(p4bridge.dll)。
异常如下:
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)
我已经了解与“垃圾回收委托”相关的消息。似乎在某些地方将委托指针传递给非托管库,然后GC将其回收。
我们查看了该API的源代码。我们看到了一些可能导致该错误的原因。但是这只是一个想法。
在调查故障时,我们创建了另一个引用了该移植库的.net框架应用程序,然后我们没有遇到任何.net框架中的错误。
我的问题是:
1. .net框架和.net core在垃圾收集机制方面有什么区别吗? 2. 怎么可能,.net框架和.net core以不同的方式响应相同的库?
fixed
块的持续时间内定义良好;对于大多数长期场景,您需要通过GCHandle
处理手动固定;这种类型的P/Invoke代码很容易出错。因此:如果它是错误的,我们又处于未定义的领域,在那里错误的代码可以“工作”,但只能在小范围内“工作”;我不会惊讶于这种代码在框架切换时变得脆弱。 - Marc Gravell