它是一个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中,它使用单例来保持调用之间的状态.这样它只需要初始化一次并从磁盘和数据库加载一堆缓慢的东西而不是每个webservice调用,因为这太慢了.
因此,对非托管.dll的每次调用首先调用Getinstance(),如果实例为null,则初始化它并重新加载所有内容,如果不是,则假定它已准备就绪.
每次在Web服务中都不会调用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,那么只要(“[我]黄金链接器我经常故意省略析构函数,因为很多数据结构的生命直播程序;在这种情况下,析构函数仅用于减慢程序退出“;是的,我知道黄金链接器不能在Windows上运行,但原理仍然适用).
如果你在谈论内核无法保证的东西,那么我建议提供一个处理PROCESS_DETACH消息的DllMain函数来处理任何需要的卸载.
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参考计数或Mutex
es
作为记录;我不喜欢这种架构(图书馆里的单身人士).我建议使用一个库,其中有问题的状态存储在对象中.库API可以是类似C的(导出函数,CreateXxxObject()/ DestroyXxxObject()函数,它们返回指向不透明结构的指针,类似于APR)或C类.单身人士模型不会削减它.
但是,我只回答问题,而不是说“首先,抛出你的计划,……”
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。