草庐IT

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

coder 2024-02-25 原文

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

它是一个 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# - 从 ASP.NET webservice 调用有状态的非托管 C++ 类的更多相关文章

  1. ruby - 在 Ruby 程序执行时阻止 Windows 7 PC 进入休眠状态 - 2

    我需要在客户计算机上运行Ruby应用程序。通常需要几天才能完成(复制大备份文件)。问题是如果启用sleep,它会中断应用程序。否则,计算机将持续运行数周,直到我下次访问为止。有什么方法可以防止执行期间休眠并让Windows在执行后休眠吗?欢迎任何疯狂的想法;-) 最佳答案 Here建议使用SetThreadExecutionStateWinAPI函数,使应用程序能够通知系统它正在使用中,从而防止系统在应用程序运行时进入休眠状态或关闭显示。像这样的东西:require'Win32API'ES_AWAYMODE_REQUIRED=0x0

  2. ruby-on-rails - 如何优雅地重启 thin + nginx? - 2

    我的瘦服务器配置了nginx,我的ROR应用程序正在它们上运行。在我发布代码更新时运行thinrestart会给我的应用程序带来一些停机时间。我试图弄清楚如何优雅地重启正在运行的Thin实例,但找不到好的解决方案。有没有人能做到这一点? 最佳答案 #Restartjustthethinserverdescribedbythatconfigsudothin-C/etc/thin/mysite.ymlrestartNginx将继续运行并代理请求。如果您将Nginx设置为使用多个上游服务器,例如server{listen80;server

  3. ruby-on-rails - 跳过状态机方法的所有验证 - 2

    当我的预订模型通过rake任务在状态机上转换时,我试图找出如何跳过对ActiveRecord对象的特定实例的验证。我想在reservation.close时跳过所有验证!叫做。希望调用reservation.close!(:validate=>false)之类的东西。仅供引用,我们正在使用https://github.com/pluginaweek/state_machine用于状态机。这是我的预订模型的示例。classReservation["requested","negotiating","approved"])}state_machine:initial=>'requested

  4. 使用 ACL 调用 upload_file 时出现 Ruby S3 "Access Denied"错误 - 2

    我正在尝试编写一个将文件上传到AWS并公开该文件的Ruby脚本。我做了以下事情:s3=Aws::S3::Resource.new(credentials:Aws::Credentials.new(KEY,SECRET),region:'us-west-2')obj=s3.bucket('stg-db').object('key')obj.upload_file(filename)这似乎工作正常,除了该文件不是公开可用的,而且我无法获得它的公共(public)URL。但是当我登录到S3时,我可以正常查看我的文件。为了使其公开可用,我将最后一行更改为obj.upload_file(file

  5. c# - 如何在 ruby​​ 中调用 C# dll? - 2

    如何在ruby​​中调用C#dll? 最佳答案 我能想到几种可能性:为您的DLL编写(或找人编写)一个COM包装器,如果它还没有,则使用Ruby的WIN32OLE库来调用它;看看RubyCLR,其中一位作者是JohnLam,他继续在Microsoft从事IronRuby方面的工作。(估计不会再维护了,可能不支持.Net2.0以上的版本);正如其他地方已经提到的,看看使用IronRuby,如果这是您的技术选择。有一个主题是here.请注意,最后一篇文章实际上来自JohnLam(看起来像是2009年3月),他似乎很自在地断言RubyCL

  6. C# 到 Ruby sha1 base64 编码 - 2

    我正在尝试在Ruby中复制Convert.ToBase64String()行为。这是我的C#代码:varsha1=newSHA1CryptoServiceProvider();varpasswordBytes=Encoding.UTF8.GetBytes("password");varpasswordHash=sha1.ComputeHash(passwordBytes);returnConvert.ToBase64String(passwordHash);//returns"W6ph5Mm5Pz8GgiULbPgzG37mj9g="当我在Ruby中尝试同样的事情时,我得到了相同sha

  7. java - 从 JRuby 调用 Java 类的问题 - 2

    我正在尝试使用boilerpipe来自JRuby。我看过guide从JRuby调用Java,并成功地将它与另一个Java包一起使用,但无法弄清楚为什么同样的东西不能用于boilerpipe。我正在尝试基本上从JRuby中执行与此Java等效的操作:URLurl=newURL("http://www.example.com/some-location/index.html");Stringtext=ArticleExtractor.INSTANCE.getText(url);在JRuby中试过这个:require'java'url=java.net.URL.new("http://www

  8. ruby - 字符串文字中的转义状态作为 `String#tr` 的参数 - 2

    对于作为String#tr参数的单引号字符串文字中反斜杠的转义状态,我觉得有些神秘。你能解释一下下面三个例子之间的对比吗?我特别不明白第二个。为了避免复杂化,我在这里使用了'd',在双引号中转义时不会改变含义("\d"="d")。'\\'.tr('\\','x')#=>"x"'\\'.tr('\\d','x')#=>"\\"'\\'.tr('\\\d','x')#=>"x" 最佳答案 在tr中转义tr的第一个参数非常类似于正则表达式中的括号字符分组。您可以在表达式的开头使用^来否定匹配(替换任何不匹配的内容)并使用例如a-f来匹配一

  9. ruby - 调用其他方法的 TDD 方法的正确方法 - 2

    我需要一些关于TDD概念的帮助。假设我有以下代码defexecute(command)casecommandwhen"c"create_new_characterwhen"i"display_inventoryendenddefcreate_new_character#dostufftocreatenewcharacterenddefdisplay_inventory#dostufftodisplayinventoryend现在我不确定要为什么编写单元测试。如果我为execute方法编写单元测试,那不是几乎涵盖了我对create_new_character和display_invent

  10. ruby - Net::HTTP 获取源代码和状态 - 2

    我目前正在使用以下方法获取页面的源代码:Net::HTTP.get(URI.parse(page.url))我还想获取HTTP状态,而无需发出第二个请求。有没有办法用另一种方法做到这一点?我一直在查看文档,但似乎找不到我要找的东西。 最佳答案 在我看来,除非您需要一些真正的低级访问或控制,否则最好使用Ruby的内置Open::URI模块:require'open-uri'io=open('http://www.example.org/')#=>#body=io.read[0,50]#=>"["200","OK"]io.base_ur

随机推荐