多线程,是狐友们的意难平,谁能搞定它价值百万。

 本文介绍了 ChristofWollenhaupt 的 DMULT.DLL  -  一个为你的Visual FoxPro应用程序提供多线程功能的 "辅助 "工具。Christof 的 DLL是迄今为止我发现的在自己的应用程序中添加多线程功能的最简单的方法。

KevinRagsdale

TheNet Results

Voice:931-409-9899

Email: kevin@kevinragsdale.nethttp://kevinragsdale.net

Twitter:@KevinRagsdale

 翻译:xinjie

Power by www.deelp.com

简介

这一切都源于《微软Visual FoxPro顾问指南》2006年9月号上的一个简单问题。

问题:如果我可以在后台线程中运行,许多事情就更容易做了。有没有一种方法可以在VFP中创建多线程应用程序?

 该问题由特约编辑Christof Wollenhaupt做出回答。

他的答复:这个问题有一个明确的答案。这取决于(你认为什么是多线程应用程序)。

从VFP6 ServicePack 3开始,我们就有能力在Visual FoxPro中创建多线程的DLLs。但这并不意味着我们在创建多线程应用程序,我们只是在创建多线程的DLLs。当你实例化一个位于DLL中的COM服务时,Visual FoxPro只能将其加载到与主程序相同的线程中。

实质上,如果你的DLL正在执行 "一个漫长的处理过程",Visual FoxPro(你的应用程序)必须等待 "一个漫长的处理过程 "完成才能继续。这可能会使用户感到困惑,因为你的应用程序对用户的操作没有反应,同时也为Windows在你的应用程序的标题栏上附加一个不那么漂亮的"(停止响应)"(图1)。

图片

1: Windows 提供的"有用的停止响应消息

 

本文介绍了Christof编写的一个C++ DLL "辅助工具",他在上面提到的解答部分做了进一步的详细解释。

01—到底什么是多线程?

依据我在书本、文章和无数谷歌搜索中看到的关于多线程的所有定义,多线程就是:在一个应用程序中同时执行多个活动的能力。如今,随着我们的多核CPU的出现,这一点更加真实。

来自维基百科:在单个处理器上,多线程通常通过分时复用(如多任务)发生:处理器在不同的线程之间切换。这种上下文切换通常发生得足够频繁,以至于用户认为这些线程或任务是在同一时间运行。在多处理器或多核系统上,线程或任务实际上是同时运行的,每个处理器或内核都在运行一个特定的线程或任务。

On a single processor, multithreading generally occurs by time-division multiplexing (asin multitasking): the processor switches between different threads. Thiscontext switching generally happens frequently enough that the user perceivesthe threads or tasks as running at the same time. On a multiprocessor ormulti-core system, the threads or tasks will actually run at the same time,with each processor or core running a particular thread or task.

来源:http://en.wikipedia.org/wiki/Multithreaded

02—多线程的优势有哪些?

对我来说,多线程的第一大优势很简单:应用程序用户界面的响应速度。 

以前有人说过很多次,对于用户来说,你的应用程序的用户界面就是应用程序。根据我的经验,没有什么比一个没有反应的用户界面更让人觉得糟糕的用户界面(和糟糕的应用程序)了。

另一个优点是能够在不打断用户工作流程的情况下执行必要和/或可选的功能。我在几个应用程序中使用多线程请求,在后台检查程序的更新。如果发现有更新,应用程序会向用户通知其可用性。另一个应用程序在后台从几个不同的网站拉取各种信息,解析信息,写入表格等,当用户在应用程序中做其他事情时,根本没有意识到后台有多少工作在进行。简而言之,即使在忙于执行多项任务的情况下,该应用程序仍然对用户有反应。

03—“一个漫长的处理过程” 的简单示例

让我们来看看一个由多线程DLL中的SomeLengthyProcess触发的无响应UI。

我有一个名为SAMPLE.PJX的项目,它包含一个名为SAMPLEMAIN.PRG,我把这个项目编译成一个多线程的DLL(SAMPLE.DLL在本次会议的源代码中)。

下面是SAMPLEMAIN.PRG的代码:

DEFINE CLASS EasyMTServer As Session OLEPUBLIC     PROCEDURE SomeLengthyProcess (toCallback)        ** 我们需要声明 Sleep 这个 Windows API 函数      ** 确保进程可以持续 20 秒       DECLARE Sleep IN WIN32API Long        ** 创建一个 FOR/ENDFOR 循环       LOCAL lnCount As Integer        ** 在 VFP 主窗口输出一个字符串      FOR lnCount = 1 TO 20         ** 在 VFP 主窗口输出 SYS(2015)的值        toCallback.DoCmd("? + ALLTRIM(SYS(2015))")          ** 等待 1 秒        Sleep(1000)       ENDFOR              ** 输出字符串 “Done!”       toCallback.DoCmd("? + 'Done!'")           CLEAR DLLS "Sleep"     ENDPROC   ENDDEFINE     

看起来是一个漫长的过程,对吗?它应该需要20秒的时间来运行。在实例化COM服务(DLL)后,我将调用SomeLengthyProcess方法,并传入_VFP对象作为回调。在20秒内,DLL将创建一个SYS(2015)字符串(每秒一次),并告诉_VFP将该字符串写出到VFP主窗口。

从VFP命令窗口调用DLL看起来像这样:

loDLL = CREATEOBJECT("sample.EasyMTServer")  loDLL.SomeLengthyProcess(_VFP) 

完美!我有了一个多线程的DLL,它在20秒内一直在忙碌,向VFP写回数据,以便我看到它在做什么。我有一个多线程的DLL,它保持20秒的忙碌,向我的VFP会话写回数据,这样我就可以看到它在做什么。但是,有一个问题。

我的VFP会话没有反应(图2)。我可以随意点击、双击甚至三击任何地方,但当SomeLengthyProcess运行时,什么也没有发生!我的VFP会话没有反应(图2)。

图片

图 2:在单线程中并不能实现真正的多线程

在 VFP窗口周围点击会导致Windows在标题栏上附加之前显示的"停止响应 "信息。有时,VFP窗口(或您的应用程序)会褪色(图3),在Windows Vista/Windows 7中,您(或您的用户)可能会看到类似图4中的信息。

图片

3: 一个没有反应的应用程序,被Windows淡化了

图片

4: 当你的应用程序没有反应时,就不是很好玩儿的事了

正如我在简介中写的那样(根据Christof顾问回答中的信息),当你实例化一个位于DLL中的COM服务时,VFP只能将其加载到与主程序相同的线程中。因此,当SomeLengthyProcess在运行时,VFP IDE是不可用的。

04—一些 “辅助”工具

然而,正如Christof进一步解释的那样,并不是没有可能实现。即使你在VFP中创建了一个MTDLL,你也需要一个额外的辅助工具来创建一个新线程,初始化内存空间,并加载COM服务。

据我所知,有三个这样的"辅助 "工具(Christof在他的回答中都提到了这些工具):

•      Remus Rusano 的 VFPMTAPP.DLL

•      来自 Calvin Hsia 博客的代码

•      Christof 的 DMULT.DLL

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

加菲猫的VFP

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值