注册 登录
编程论坛 VFP论坛

如何让程序预定执行一段代码(定时或闲时)

大树临风 发布于 2021-03-11 08:58, 4167 次点击
想让程序定时或者闲时,自动运行一段代码,请教各位
28 回复
#2
吹水佬2021-03-11 09:19
因VFP是单线程工作,具体要看这段代码是做什么才能更好地实现。
#3
大树临风2021-03-11 09:36
回复 2楼 吹水佬
哦,就是一个简单的显示信息,不是调用外部的程序,我想用timer应该可以吧,实现每个小时运行一次
#4
吹水佬2021-03-11 10:56
回复 3楼 大树临风
timer是定时器,也是工作在单线程,要注意的是timer有可能“不定时”或“不准时”,甚至是“没有时”。
#5
大树临风2021-03-11 11:40
回复 4楼 吹水佬
感谢版主,单线程意味着timer触发后,会造成主程序的“卡顿”是吧,那有没有什么更好的办法?
我的目的就是定时从腾讯云COS上读取一段文本信息,然后显示出来。

提到单线程,想起来每次编译EXE时VFP弹出的对话框,其中的单线程dll和多线程dll又是什么意思呢,是不是也可以做多线程的开发


[此贴子已经被作者于2021-3-11 11:47编辑过]

#6
吹水佬2021-03-11 11:52
以下是引用大树临风在2021-3-11 11:40:02的发言:

感谢版主,单线程意味着timer触发后,会造成主程序的“卡顿”是吧,那有没有什么更好的办法?
我的目的就是定时从腾讯云COS上读取一段文本信息,然后显示出来

试试可以接受就OK,如果主程序中其他过程和timer过程耗时不大和不要求过高的“定时和准时”应该还可以。
#7
吹水佬2021-03-11 11:55
回复 5楼 大树临风
要求高的话就用多进程(另一个进程EXE)来处理,因VFP不方便使用多线程,相对系统来说多进程也是多线程。
#8
radiofan2021-03-11 12:10
以下是引用吹水佬在2021-3-11 10:56:28的发言:

timer是定时器,也是工作在单线程,要注意的是timer有可能“不定时”或“不准时”,甚至是“没有时”。


有什么改变的方法?我的系统同步程序就偶尔会出现这个情况,定时器无缘无故就停止在某一个时刻!
#9
吹水佬2021-03-11 12:52
回复 8楼 radiofan
定时器的级别很低,其他任务太忙时有可能会被放弃
#10
radiofan2021-03-11 13:17
以下是引用吹水佬在2021-3-11 12:52:43的发言:

定时器的级别很低,其他任务太忙时有可能会被放弃


有什么有效的改善方法或者其他办法?谢谢!
#11
吹水佬2021-03-11 14:58
回复 10楼 radiofan
可以参考7楼
#12
吹水佬2021-03-11 15:11
以下是引用大树临风在2021-3-11 11:40:02的发言:


提到单线程,想起来每次编译EXE时VFP弹出的对话框,其中的单线程dll和多线程dll又是什么意思呢,是不是也可以做多线程的开发

编译生成dll,是一个COM组件,注册后就好象控件一样使用。
可编译成支持多线程的DLL,即可在多个子线程中使用,并不是说这个DLL里面就有多线程的东西。
#13
radiofan2021-03-11 16:21
以下是引用吹水佬在2021-3-11 14:58:37的发言:

可以参考7楼


没有明白?
#14
吹水佬2021-03-11 18:49
以下是引用radiofan在2021-3-11 16:21:56的发言:



没有明白?

意思是本来由一个人去做的事改为由多人分工协作共同去做
#15
radiofan2021-03-11 20:03
以下是引用吹水佬在2021-3-11 18:49:57的发言:


意思是本来由一个人去做的事改为由多人分工协作共同去做


你的意思是用定时器去触发另一个exe去做后台同步数据?

也许,thisform.timer.enabled = .F.,让定时器暂时停止运行 ……

[此贴子已经被作者于2021-3-11 20:20编辑过]

#16
吹水佬2021-03-11 20:25
回复 15楼 radiofan
不要用定时器来启动一个EXE,就是运行一个外部EXE,按需要适时启动或关闭
#17
radiofan2021-03-12 08:20
以下是引用吹水佬在2021-3-11 20:25:41的发言:

不要用定时器来启动一个EXE,就是运行一个外部EXE,按需要适时启动或关闭


那这个exe何时启动,何时关闭,谁来调度呢?
#18
吹水佬2021-03-12 09:37
回复 17楼 radiofan
几个人协同做事相互间可以沟通
了解一下“进程间通信”,进程间通信方式有多种,可视实际情况选择一种或多种灵活运用。
#19
radiofan2021-03-12 10:06
以下是引用吹水佬在2021-3-12 09:37:12的发言:

几个人协同做事相互间可以沟通
了解一下“进程间通信”,进程间通信方式有多种,可视实际情况选择一种或多种灵活运用。


举个简单例子吧,谢谢!
#20
吹水佬2021-03-12 12:12
最简单的示例(消息)
只有本站会员才能查看附件,请 登录

只有本站会员才能查看附件,请 登录

程序代码:
** 主进程
** test1.exe
**
cDefPath = ADDBS(JUSTPATH(SYS(16)))
_screen.Visible = .F.
DECLARE LONG SendMessage IN User32 LONG, LONG, LONG, LONG
of = CREATEOBJECT("Form1")
of.show
READ EVENTS
RETURN

DEFINE CLASS Form1 as Form
    ShowWindow = 2
    hSubpro = 0
    ADD OBJECT cmd as CommandButton WITH top=10,left=10,height=22,caption="启动子进程"
    ADD OBJECT edt as EditBox WITH top=40,left=10,width=300,height=200
   
    PROCEDURE Init
        BINDEVENT(this.hWnd, 0x401, this, "_Message")
    ENDPROC
   
    PROCEDURE Destroy
        IF this.hSubpro > 0
            SendMessage(this.hSubpro, 0x401, 0, 0)
        ENDIF
        CLEAR EVENTS
    ENDPROC
   
    PROCEDURE cmd.Click
        oApp = CREATEOBJECT("Shell.Application")
        oApp.ShellExecute(cDefPath+"test2.exe", TRANSFORM(thisform.hWnd), "", "", 1)
    ENDPROC

    PROCEDURE _Message(hWnd, nMsg, wParam, lParam)
        DO CASE
            CASE wParam == 1
                this.edt.SelText = "子进程启动" + 0h0D0A
                this.hSubpro = lParam
            CASE wParam == 2
                this.edt.SelText = "子进程关闭" + 0h0D0A
        ENDCASE
    ENDPROC
ENDDEFINE


程序代码:
** 子进程
** test2.exe
**
PARAMETERS cParam
_screen.Visible = .F.
DECLARE LONG SendMessage IN User32 LONG, LONG, LONG, LONG
of = CREATEOBJECT("Form1", cParam)
of.show
READ EVENTS
RETURN

DEFINE CLASS Form1 as Form
    ShowWindow = 2
    AutoCenter = 1
    hMain = 0
   
    PROCEDURE Init(cParam)
        this.hMain = INT(VAL(cParam))
        SendMessage(this.hMain, 0x401, 1, this.hWnd)
        BINDEVENT(this.hWnd, 0x401, this, "_Message")
    ENDPROC
   
    PROCEDURE Destroy
        IF this.hMain> 0
            SendMessage(this.hMain, 0x401, 2, 0)
        ENDIF
        CLEAR EVENTS
    ENDPROC
   
    PROCEDURE _Message(hWnd, nMsg, wParam, lParam)
        DO CASE
            CASE wParam == 0
                MESSAGEBOX("主程序关闭")
                this.Release
            CASE wParam == 1
            CASE wParam == 2
        ENDCASE
    ENDPROC
ENDDEFINE



[此贴子已经被作者于2021-3-12 12:20编辑过]

#21
radiofan2021-03-12 16:35
回复 20楼 吹水佬
感谢!有空研究一下。
#22
radiofan2021-03-12 16:46
以下是引用吹水佬在2021-3-12 12:12:12的发言:

最简单的示例(消息)

** 主进程
** test1.exe
**
cDefPath = ADDBS(JUSTPATH(SYS(16)))
_screen.Visible = .F.
DECLARE LONG SendMessage IN User32 LONG, LONG, LONG, LONG
of = CREATEOBJECT("Form1")
of.show
READ EVENTS
RETURN

DEFINE CLASS Form1 as Form
    ShowWindow = 2
    hSubpro = 0
    ADD OBJECT cmd as CommandButton WITH top=10,left=10,height=22,caption="启动子进程"
    ADD OBJECT edt as EditBox WITH top=40,left=10,width=300,height=200
   
    PROCEDURE Init
        BINDEVENT(this.hWnd, 0x401, this, "_Message")
    ENDPROC
   
    PROCEDURE Destroy
        IF this.hSubpro > 0
            SendMessage(this.hSubpro, 0x401, 0, 0)
        ENDIF
        CLEAR EVENTS
    ENDPROC
   
    PROCEDURE cmd.Click
        oApp = CREATEOBJECT("Shell.Application")
        oApp.ShellExecute(cDefPath+"test2.exe", TRANSFORM(thisform.hWnd), "", "", 1)
    ENDPROC

    PROCEDURE _Message(hWnd, nMsg, wParam, lParam)
        DO CASE
            CASE wParam == 1
                this.edt.SelText = "子进程启动" + 0h0D0A
                this.hSubpro = lParam
            CASE wParam == 2
                this.edt.SelText = "子进程关闭" + 0h0D0A
        ENDCASE
    ENDPROC
ENDDEFINE


** 子进程
** test2.exe
**
PARAMETERS cParam
_screen.Visible = .F.
DECLARE LONG SendMessage IN User32 LONG, LONG, LONG, LONG
of = CREATEOBJECT("Form1", cParam)
of.show
READ EVENTS
RETURN

DEFINE CLASS Form1 as Form
    ShowWindow = 2
    AutoCenter = 1
    hMain = 0
   
    PROCEDURE Init(cParam)
        this.hMain = INT(VAL(cParam))
        SendMessage(this.hMain, 0x401, 1, this.hWnd)
        BINDEVENT(this.hWnd, 0x401, this, "_Message")
    ENDPROC
   
    PROCEDURE Destroy
        IF this.hMain> 0
            SendMessage(this.hMain, 0x401, 2, 0)
        ENDIF
        CLEAR EVENTS
    ENDPROC
   
    PROCEDURE _Message(hWnd, nMsg, wParam, lParam)
        DO CASE
            CASE wParam == 0
                MESSAGEBOX("主程序关闭")
                this.Release
            CASE wParam == 1
            CASE wParam == 2
        ENDCASE
    ENDPROC
ENDDEFINE


在主进程中启动子进程还是要用到timer ……,如果每分钟启动子进程一次!
#23
吹水佬2021-03-12 18:47
以下是引用radiofan在2021-3-12 16:46:35的发言:



在主进程中启动子进程还是要用到timer ……,如果每分钟启动子进程一次!

每分钟启动子进程一次就没必要。
启动子进程后就可以一直工作,直到完成整个任务,什么时候需要子进程做什么是可以控制。
#24
radiofan2021-09-24 10:28
以下是引用吹水佬在2021-3-12 18:47:39的发言:


每分钟启动子进程一次就没必要。
启动子进程后就可以一直工作,直到完成整个任务,什么时候需要子进程做什么是可以控制。


嗯,我的意思是:主进程中定时启动子进程还是要用到timer !比如在整点运行子程序1,在每个分钟点,如果满足特定条件运行子程序2 等等 ……
#25
xuminxz2021-09-24 10:52
似乎可以用windows的计划任务程序,来调用你的程序。
#26
radiofan2021-09-24 11:00
以下是引用xuminxz在2021-9-24 10:52:42的发言:

似乎可以用windows的计划任务程序,来调用你的程序。


计划任务不能检索和判断我的需求
#27
nbwww2021-09-24 19:44
以下是引用radiofan在2021-9-24 11:00:35的发言:



计划任务不能检索和判断我的需求

计划任务定时启动你的程序  程序打开后判断需求   符合就执行后续部分   没有就退出
到下个时间点又会启动你的程序   理论上符合你的要求的
#28
独木星空2021-09-25 07:15
回复 20楼 吹水佬
有空学习一下。并加以运用。
#29
radiofan2021-09-26 08:30
只有本站会员才能查看附件,请 登录


吹版的思路不错,定时程序测试中,每整点运行二号进程,其他时间每隔一分钟运行其他进程。

[此贴子已经被作者于2021-9-26 09:40编辑过]

1