我正在使用 3.9.7 cURL 库从 Internet 下载文件,所以我创建了一个动态 bibioteca of viculo。使用 VC++ 6.0 用 C 语言编写的 dll 问题是,当我从我的 vb6 应用程序窗口中调用我的函数时,只有在你下载了文件后才会锁定和解锁,我该如何解决这个问题?
2 回答
问题是,当您从 DLL 调用该函数时,它会“阻止”您的应用程序的执行,直到它完成。基本上,执行从进行函数调用的一段代码,到函数调用内部的代码,然后在函数内部的代码完成运行后才返回到函数调用之后的下一行。事实上,这就是所有函数调用的工作方式。您可以通过在 VB 6 开发环境中单步执行代码来亲自了解这一点。
您通常不会注意到这一点,因为在将控制权返回给调用者之前,被调用函数内部的代码不会花费很长时间来执行。但是在这种情况下,由于您从 DLL 调用的函数正在执行大量处理,因此需要一段时间才能执行,因此它会“阻塞”您的应用程序代码的执行一段时间。
对于您的应用程序窗口似乎被冻结的原因,这是一个很好的一般解释。从技术上讲,这是因为负责处理用户与屏幕元素交互的消息泵没有运行(它是您的代码的一部分,在您调用的函数完成处理之前暂时挂起)。对于 VB 程序员来说,这有点难以理解,因为这些细节都没有在 VB 世界中暴露出来。这一切都发生在幕后,就像在 C 程序中一样,但您通常不必处理任何事情。但是,有时抽象会泄漏,细节会抬起丑陋的脑袋。这是其中一种情况。
正如其他人所暗示的那样,这个一般问题的正确解决方案是在后台线程上运行冗长的操作。这使您的主线程(现在,您唯一拥有的一个,您的应用程序正在运行的那个)可以自由地继续处理用户输入,而另一个线程可以处理数据并将处理过的数据返回给主线程完成的。当然,计算机实际上一次只能做一件事,但操作系统在一项任务和另一项任务之间快速切换的魔力意味着你可以模拟这一点。这样做的机制涉及线程。
问题在于 VB 6 环境不支持创建多线程。你只会得到一个线程,这就是你的应用程序运行的主线程。如果您冻结该程序的执行,即使是暂时的,您的应用程序也会冻结——正如您已经发现的那样。
但是,如果您已经在编写 C++ DLL,那么您没有理由不能在 VB 6 应用程序中创建多个线程。您只需要自己处理所有事情,就好像您在使用另一种较低级别的语言(如 C++)一样。在后台线程上运行 C++ 代码,只有在完全完成后才将其结果返回给主线程。同时,您的主线程是免费的。
不过,这仍然是一项相当多的工作,尤其是当您在 Win32 编程和围绕多线程的问题方面缺乏经验时。找到支持开箱即用的异步函数调用的不同库可能会更容易。Antagony 建议使用 VB 的AsyncRead
方法。这可能是一个不错的选择;正如 Karl Peterson 在链接文章中所说,它将所有内容都保存在纯 VB 6 代码中,这可以节省时间,也可以为未来的维护程序员带来福音。唯一的问题是,一旦获得数据,您仍然必须以某种方式处理数据。如果这很慢,那么您就回到了起点……
查看这篇文章,它演示了如何在用户控件中使用鲜为人知的方法异步传输大文件。