c# - 从 ASP.NET webservice 调用有状态的非托管 C++ 类

标签 c# asp.net c++ web-services unmanaged

我继承了一个完成了一半的应用程序,它似乎使用了一个我不确定能否可靠工作的模型。

它是一个 ASP.NET web 服务,在每次调用时加载一个非托管的 C++ .DLL 使用

[DllImport ( "kernel32.dll" , EntryPoint = "LoadLibraryA" )]
public static extern int LoadLibrary( string lpLibFileName );

然后对其进行多次调用,例如

 [DllImport(@"MyUnamanagedDLL.dll")]
 public static extern string DoStuff( );

在非托管 C++ .dll 中,它使用单例来保持调用之间的状态。这样一来,它只需初始化一次并从磁盘和数据库加载一堆缓慢的东西,而不是在每次 web 服务调用时加载,因为这太慢了。

因此,每次调用非托管 .dll 时,如果实例为 null,则首先调用 Getinstance(),它会初始化它并重新加载所有内容,否则,它会假定它已准备就绪。

FreeLibrary 并不是每次都在网络服务中被调用,因为我认为这会导致非托管类每次都必须重新初始化。

这个模型可靠吗?您能否确保在关闭 Web 服务时正确清除非托管状态?您能否确保在 loadlibrary 调用之间可靠地获得有效的单例实例?

最佳答案

Is this model at all reliable? Can you ensure that if the webservice is shut down that the unmanaged state is cleaned up properly?

答案取决于几件事;首先:什么样的状态?如果您正在查看内核从根本上负责的事情——内存、文件句柄、HWND——那么 you can expect the kernel to clean up when the library is unloaded , 每当那是 ([我] 在黄金链接器中,我经常故意省略析构函数,因为许多数据结构在程序的生命周期中存在;在这种情况下,析构函数仅用于减慢程序退出速度”;是的,我知道 gold 链接器不能在 Windows 上运行,但原理仍然适用。

如果您谈论的是内核无法保证的事情,那么我建议提供一个 DllMain 函数来处理 PROCESS_DETACH 消息以处理任何需要的卸载。

Can you ensure you will reliably get a valid singleton instance between loadlibrary calls?

简单的情况是:

  • 单例不存在
  • 进程A需要单例,创建并使用它
  • 进程 B 需要单例,看到它已经存在,使用它
  • 进程 A 和 B 不再需要单例,它被清理干净了
  • 单例不存在
  • 进程C需要单例,创建并使用它
  • ...

更困难的情况将涉及创建或清理时的竞争条件:

  • 单例不存在
  • 进程A需要单例,开始创建它
  • 在进程 A 完成之前,进程 B 需要单例,创建它;这是个问题
  • 进程 A 和 B 不再需要单例,开始清理它
  • 在清除单例之前,进程 C 需要它,看到它存在并尝试使用它;这是个问题

这些是典型的竞争条件,解决方案是确保检查/创建步骤(和检查/清理)是原子的。不要花哨。使用 atomic引用计数或 Mutexes


备案;我不喜欢这种架构(图书馆里的单例)。相反,我会推荐一个库,其中有问题的状态存储在对象中。库 API 可以是 C 类的(导出函数,CreateXxxObject()/DestroyXxxObject() 函数返回指向不透明 struct 的指针,类似于 APR ),或 C++ 类。总有一天单例模型无法解决问题。

但是,我只是回答问题,而不是说“首先,放弃你的计划,......”

关于c# - 从 ASP.NET webservice 调用有状态的非托管 C++ 类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4382852/

上一篇:c++ - 友元函数

下一篇:c++ - 集合的实现

相关文章:

c# - TwoWay 将日期时间绑定(bind)到文本框 - 仅年份

javascript - 在 JavaScript 中创建复杂的 HTML

c# - 如何在 Web 应用程序(ASP.Net、C#、IIS)中上传文件

c++ - 为什么这两段代码给我不同的结果?

c# - Web API未接收序列化对象的json

C# 在下一行之前等待或暂停 X 秒

asp.net - 如何将 Angular Material 添加到 asp.net Angular 模板

c++ - 如何使用 PeekMessage 检索除输入(鼠标+键盘)之外的所有消息

c++ - 如何在 Vulkan 中获取下一帧呈现时间

c# - 使用 TFS 获得最新版本,是否可以在执行 'take server version' 后还原文件?