【问题标题】:Close a C#/C++ DLLImport or atleast deallocate its heap memory? [closed]关闭 C#/C++ DLLImport 或至少释放其堆内存? [关闭]
【发布时间】:2021-04-19 23:40:42
【问题描述】:

我有一个 C# .NET Framework 应用程序,它通过 DLLImport 调用非托管 C++ DLL,以解析用户提供的一堆文件并执行一些操作。

我想在我的 C# 应用程序上有一个进度条,因为这个文件解析可能是一个漫长的过程。我认为最好的方法是一次解析几个文件,然后返回 C# 代码,这样我就可以更新进度条了。

但是,这需要我在 C++ DLL 的堆上分配一些内存,这样我就不必在每次必须再次调用 C++ 函数时将所有 10,000 多个文件路径作为参数传递。

我不确定在完成解析后是否可以关闭 DLL。有没有其他方法可以完成这项任务,而不必在应用程序运行的整个时间内保留分配的内存中的所有路径?

【问题讨论】:

  • 我被这个描述弄糊涂了。请显示您的实际代码,并解释您在其中遇到的问题。在添加进度条之前,您是如何跟踪需要处理的文件的?为什么仅仅因为你添加了一个进度条就会改变呢?至于关闭C+ DLL,见Unload a DLL loaded using DllImport
  • 通常在 P/Invoking 时,您提供一个函数来分配资源,如果需要持有资源,则提供另一个函数来解除分配。或者被调用的代码应该在返回之前自行清理。
  • 无论如何你是从哪里加载路径的,难道你不能只是延迟加载每个路径并在准备好后传递给 DLL 吗?
  • 但是,对于进度条,您可以做的最好的事情是提供对非托管代码的回调,其中托管端相应地更新显示。
  • @brickbobed 这里有几个单独的问题:1)更新进度条; 2)卸载非托管DLL; 3)将大批量分成小块。您的应用程序是否需要一次处理整个 10k 组文件,还是这些文件是独立的?要从内存中卸载 DLL,请使用 FreeLibrary 或类似工具。只要您的代码不包含对非托管内存的引用,它通常是安全的。

标签: c# c++ .net dllimport


【解决方案1】:

既然您已经确认文件是独立的,您应该尝试并行化操作。

在流程的生产者端,设置一个带有文件名的列表或数组。如果列表变得太大(真的,真的很大,所以它强调可用 RAM),您可能希望将其替换为 BlockingCollection 和队列的组合,因此可以限制生产者,直到处理管道中的项目数低于阈值.

在此管道的另一端,启动一个工作线程(内联或作为单独的工作线程),它将按顺序或 .AsParallel() 从集合中读取项目,并将它们传递给非托管库进行处理。

由于这是一个 UI 应用程序,我想您的工作线程应该是独立的。在每个处理过的文件上,在 UI 表单上执行 .Invoke() 以更新进度条。

【讨论】:

  • 所以如果有人想知道为什么这是一个答案;一旦并行化,每个文件名只需通过托管 -> 本机转换发送一次。
  • 并行化不是必须的;关键是每次调用从单独的工作线程只发送一个文件,并通过 .Invoke() 通知 UI 线程。
猜你喜欢
  • 2015-12-16
  • 1970-01-01
  • 2014-01-21
  • 2021-07-26
  • 1970-01-01
  • 1970-01-01
  • 2014-08-29
  • 1970-01-01
  • 2020-05-01
相关资源
最近更新 更多