VFP中运行库的选择

选择运行时刻库

您或许需要一个诸如象 FoxISAPI 这样的 Internet 服务应用程序等的应用程序,以便实例化表单并将其映射为等价的 HTML。通过使用新的 Vfp6t.dll 运行时刻库删除一些非关键性功能将改善您的多线程服务应用程序的总体性能。

关于服务程序选择的一个普遍的错误概念认为,仅通过连编 .dll,应用程序就会很好地自动按比例安排使用运行时刻库。您可以这么做,但是也应该考虑有关 Visual FoxPro API 调用、分时性、重入和资源冲突的使用方面的问题。

使用 Visual FoxPro API 调用

当使用发出 Visual FoxPro API 调用的 Visual FoxPro FLL 或标准 Windows DLL 库时,在服务程序设计中,您需要考虑一些问题。Visual FoxPro 6 API 不能方便地确定一个特定的调用属于哪个项目 (.dll)。因此,存在 API 调用指向错误的项目(.dll—线程本地存储)的可能,即使可能性很小。如果您的 FLL/DLL 库在发出它的 API 调用之前,从一个不同的 Visual FoxPro .dll 服务程序创建实例,这也许会发生。如果您的服务程序遇到此问题,则有下列几种可能的解决方法:

  • 创建一个独立的 Vfp6t.dll 运行时刻库文件的副本,将该副本放在和您的 .dll 服务程序相同的文件夹中。在 Windows 系统文件夹或客户应用程序进程文件夹中定位文件之前,该服务程序将总是最先搜索您的服务程序文件夹。通过自己的运行时刻库服务,服务程序不会面临来自其他 .dll(假设这些 .dll 不在同一文件夹中)的潜在冲突。由于此行为(自动复制/运行时刻重命名)在 Vfp6r.dll 运行时刻库为默认设置,上述 API 问题仅在 Vfp6t.dll 运行时刻中才会发生。

  • 将您的应用程序限制为一个 .dll 服务程序。如果使用多个 .dll 服务程序(项目),就有可能发生 API 冲突。一个项目可以包含许多 OLEPUBLIC,而每个 OLEPUBLIC 不必拥有单独的项目。请注意在共享的计算机服务程序上,其他开发人员也可能安装了别的 Visual FoxPro COM 服务程序,如果同时运行,就有可能发生冲突。

分时性问题

在 Visual FoxPro 6 SP3 中的多线程运行时刻库很大程度提高了 Visual FoxPro 进程内服务程序的分时性能。尽管运行库自动处理服务程序的分时性,但是某些紧凑的代码循环可能不允许发生频繁的线程切换。例如,非常紧凑的 DO WHILE 循环就可能是这样的。如果遇到了分时问题,可以插入下列代码,以强制处理器切换线程:

DECLARE Sleep IN Win32API INTEGER 
SLEEP(0) 

尽管可以在单处理器计算机上使用多线程,但请注意多线程可能会导致意料不到的结果。例如,在单处理器计算机上,多线程仅在长短任务混杂的情况下可以显著地提高性能。多线程方法程序调用也可能会使速度降低。

例如,假设同时调用两个方法程序:A 和 B。在单线程组件,请求是串行,除非 A 结束否则不会开始 B。在多线程情况下,处理器将并发处理两个活动的线程。

不仅平均完成时间增加了很多,而且处理器时间花费在进程之间的切换上。问题在于方法程序 A 和 B 花费大致相同的时间量。

例如,如果 B 仅请求了三个时间片以完成任务,在方法程序 B 的响应时间内系统的用户将感觉到速度有很大的提高,仅在请求执行方法程序 A 的时间中有一些降低。

多线程显示其最大优越性是在以下情况:大多数线程花费了大量阻塞时间,例如,等待文件输入/输出,这样一来,在任意给定的时间上其他线程可以执行代码。

如果要考虑在单处理器上运行应用程序,并且线程阻塞是最小限度,可以考虑使用 Vfp6r.dll 运行时刻库。在多处理器上并且在大多数其他应用程序中,可以考虑为 .dll 服务程序使用 Vfp6t.dll。

重入

在套件模型中,重入引用以下的事件系列:

  1. 执行套件的线程重入了一个对象的代码,原因是触发了某个属性和方法程序。

  2. 当线程在属性或方法程序中时,其他线程触发了对象的属性或方法程序,Automation 连续发出请求,也就是说,Automation 对请求进行排队,直到拥有对象的套件的线程完成了其并发执行的成员。

  3. 在线程到达成员的结尾之前,它执行让出处理器控制的代码。

  4. Automation 通知线程开始执行连续的请求,这样线程就重新重入了对象的代码。

新的请求可能是针对线程正在执行的成员的(在线程再次重入成员的情况下),也可能是针对其他程序的。如果第二个成员没有退出,它将在第一个成员之前完成处理。如果它更改了第一个成员正在使用的模块级数据,则结果可能出现问题。

通过对每个套件属性和方法程序的连续调用,Automation 保护您的代码以防止重新重入,除非您的代码让出了处理器的控制。以下是在代码中让出处理器控制的方法:

  • 调用 DoEvents。

  • 在其他线程或其他进程上触发属性或方法程序。如果将 Application.AutoYield 属性设置为假 (.F.),则将在代码执行之间挂起间歇事件的处理过程。

  • 从方法程序中触发交叉线程或交叉进程方法程序。

除非已经小心地书写了所有对象的代码,使代码在同时执行两个成员的情况下不会有问题,否则就应该插入让出处理器控制的代码。

资源冲突

新的 Vfp6t.dll 运行时刻库将保护对象以避免访问其他应用程序的数据。它同时包含了声明的和内部的环境全局资源。某些资源代表了潜在的冲突问题,如下所示。

  • 文件

  • 注册表

  • 数据

文件输入/输出代表的资源冲突可以很容易地通过代码解决,因为文件管理是通过操作系统来处理的。当使用文件时,您的服务程序可以打开(并锁定)文件,以便使其他对象知道该文件正在使用。撰写正确的服务程序可以处理这种情况,方法是一直等待直至文件重新可用为止,或者通过其他较容易接受的方式处理错误。文件也可以“共享”地打开,在这种情况下,服务程序应该意识到其他对象存在更改值的可能性。

对于 INI 文件,一个常见的情况就是不同的对象可以读或写文件中的值。读出并且随后将值写入 INI 文件的进程需要两步。因此,就有可能发生这样的情况:由一个客户应用程序读出的值,如果其他客户应用程序在其更改之前更改了该值,则该值就不一定是该客户应用程序后来覆盖的同一个值,因此就需要进行冲突解决。

与 INI 文件相同,“注册表”中保存的设置也可以由多个客户应用程序访问。您的应用程序应该使用公用的 Windows API 例程来访问“注册表”(例如,REGISTRY.VCX 中的 FoxPro“基本”类)。同样,您的服务程序设计应该反映在读取键值时刻和写入键值时刻之间对“注册表”键值可能的更改。Windows API 例程工作时可以不必进行冲突解决。

“数据”是一种需要灵活处理的资源。庆幸的是,大多数在运行时刻库中可用的 Visual FoxPro 语言提供了处理资源冲突问题所需要的全部信息和功能。有关处理共享数据的详细内容,请参阅“帮助”中的“编写共享访问的程序”。

posted @ 2005-01-13 21:25  Roland  阅读(1747)  评论(0编辑  收藏  举报