# VFP也能搞多线程?不可能的,这下被啪啪打脸了

当一个耗时较长查询,只能等待,就象上了贼船,什么都干不了....懂得多懂。 VFP 应用DMULT.DLL多线程,看到了一线光明… 经过几天实践,在尽力少改原来代码前提下,封装通用类,供分享交流,不当之处,多提宝贵意见。

现在嘛,表单不卡了,某些场景感觉用起来感觉快了,有些场景确实快了。

# 一、 文件说明

DMULT.DLL 多线程DLL ThreadServer.dll VFP连编COM(要注册) procservsr.prg 接口类 test.scx 示例

# 二、DMULT.DLL

鸣谢:XinJie翻译的《在Visual FoxPro 中轻松实现多线程》 这是多线程实现的核心DLL

# 三、编写多线程com ThreadServer.dll

VFP中新建一个叫ThreadServer的项目,添加ThreadServer.prg,代码如下,

DEFINE CLASS ThreadServer As Session OLEPUBLIC  
    PROCEDURE ThreadServer  
     LPARAMETERS toCallback && 回调对象
     LOCAL oPS
      oPS=NEWOBJECT("PROCSERVSR","PROCSERVSR.prg")  
      oPS.PROCSERVSR(toCallback) && 你的程序写在PROCSERVSR过程中
   ENDPROC  
ENDDEFINE
1
2
3
4
5
6
7
8

连编多线程COM,生成叫ThreadServer 的com dll 这里有调用了另外一个VFP类PROCSERVSR,由它来执行具体的任务。

# 四、 procservsr.prg

里面放了一个调用的函数,和一个叫procservsr的类。 叫procservsr的类将在com中线程中运行,这个程序是不能有UI交互元素的,比如,Messagebox/wait/inkey等命令。

PARAMETERS CS1,CS2, CS3, CS4, CS5 
LOCAL lnHandle, lnThreadID, loCallback 
     m.lnThreadID = 0 
*====创建回调对象,CS1~CS5传参数==========
     m.loCallback = NEWOBJECT("Callback","PROCSERVSR.prg","",CS1,CS2, CS3, CS4, CS5)  
*========创建线程==================
     m.lnHandle = CreateThreadWithObject( ; 
			    Strconv("ThreadServer.ThreadServer"+Chr(0),5), ;
			    Strconv("ThreadServer"+Chr(0),5), ;
 	 	 	 	_VFP.Eval("loCallback"), ; 
 	 	 	 	@lnThreadID ; 
 	 	 	) 
 	    =CloseHandle(m.lnHandle)   
*====线程中调用方法(你的查询)==这里作等待测试====            
DEFINE CLASS PROCSERVSR As CUSTOM  
     PROCEDURE PROCSERVSR(toCallback)  
       DECLARE Sleep IN WIN32API Long
	   =Sleep(1000)
	    CLEAR DLLS "Sleep" 
       IF toCallback._CS1 =[5] 
toCallback._CS2.text1.value=ALLTRIM(toCallback._CS2.text1.value) +[|]+seep5() &&表单TEXT1写点东东
        ENDIF    
	    toCallback._CS2.text1.value=ALLTRIM(toCallback._CS2.text1.value) +[(]+toCallback._CS1+[)]
*========释放对象======================  
        THIS.RELEASE
        toCallback.RELEASE
ENDPROC         
PROCEDURE Release
		RELEASE THIS
ENDPROC  

ENDDEFINE 	

*===========你的过程===============  
 FUNCTION seep5
    RETURN [XXX]
 ENDFUNC 
 
 *=========回调对象==================
 DEFINE CLASS Callback AS CUSTOM
    _CS1=[]
    _CS2=[]
    _CS3=[]
    _CS4=[]
    _CS5=[]
 	PROCEDURE Init (CS1,CS2, CS3, CS4, CS5)
		this._CS1=CS1
	    this._CS2=CS2
	    this._CS3=CS3
	    this._CS4=CS4
	    this._CS5=CS5
	ENDPROC
   PROCEDURE Release
		RELEASE THIS
	ENDPROC
ENDDEFINE 	
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56

# 五、表单中运行

新建一个表单test,拖入一个textbox1的文本框,一个命令按钮 表单 load方法

Declare Long CreateThreadWithObject in DMult.DLL ;
				String lpszClass, ;
				String lpszMethod, ;
				Object oRef,  ;
				Long @lpdwThreadId 
		  Declare CloseHandle in Win32API LONG  
1
2
3
4
5
6

按钮click事件

	LOCAL loCallback  &&lnHandle, lnThreadID,
		FOR i=1 TO 5  &&创建5个线程
		   oCallback =PROCSERVSR(TRANSFORM(i),thisform)
		    thisform.text1.value=ALLTRIM(thisform.text1.value)+CHR(i+64)
		     =INKEY(0.1) && ABCDE 输出很快
		ENDFOR  
1
2
3
4
5
6

那么运行表单测试看看了