如何获取过程或函数中的动态变化值(200分)

  • 主题发起人 主题发起人 子瑜
  • 开始时间 开始时间

子瑜

Unregistered / Unconfirmed
GUEST, unregistred user!
如题:如何获取过程或函数中的动态变化值,如下例:
test(var varp:integer)
想在函数运行过程中,动态取出varp的值,如何实现?
完整例子如下:
unit Unit1;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;

type
TForm1 = class(TForm)
Button1: TButton;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
Function test(var varp:integer):Boolean;
end;

var
Form1: TForm1;

implementation

{$R *.dfm}
Function TForm1.test(var varp:integer):Boolean;
var
j:integer;
begin
Result:=False;
For j:=0 to 10000 do
begin
varp:=j;
application.ProcessMessages;
end;
Result:=True;
end;

procedure TForm1.Button1Click(Sender: TObject);
var
flag:boolean;
myvarp:integer;
begin
flag:=False;
repeat
flag:=test(myvarp);
Caption:=inttostr(myvarp);
application.ProcessMessages;
until Flag;
end;

end.
 
假设test函数是三层结构体系中服务端接口提供的一个函数,我在本地客户要获取test(var varp:integer) 中动态变化的值,也就这个意思吧
 
问题是,flag:=test(myvarp);要执行完test全程,才会返回继续执行,所以Caption:=inttostr(myvarp);的结果永远是 10000。
 
有什么办法在执行过程中不断返回变化值吗?主要目的是想监控此函数在执行过程中,内部值的变化返回给外部,以便外部可以知道此函数执行了多少进度?
 
全局变量啊!不然你如何监视该内存变化!
 
不要变参,用全局变量。
 
晕回掉函数呀,这样最简单 或者用同步的sendmessage消息 在在内存做内存影射文件处理。
 
全局变量有用吗?一个是运行在服务端的接口函数,一个是客服端的接口调用程序
 
在服务端建立一个全局变量(对象亦可),然后,让test接口在内部修改全局变量的值,
同时,向客户端开放另一个check接口,用于直接返回全局变量的当前值。这样,客户端就
可以及时的检测当前进度了。
 
creation-zy:
好方法,我也想过用TSocketconnection的方法直接发回给客户端一个变化值,其变化值来自于test函数中。
 
本来想用线程直接在客户端监控此函数的运行,可在线程中传递通过TSocketconnection客户端数据集_Recordset(olevariant类型),却存在问题,问题的关键是midas的bug,把TSocketconnection的supportcallbacks置为false时,_Recordset(olevariant类型)作为参数传给服务端却出现bug问题,数据集读不出来,如果supportcallbacks置为true,,_Recordset(olevariant类型)数据集能正常读出,但是却不能在线程中运行Socketconnection1.appserver的函数。
 
其实我问test这个例子只是想解决我的一个设想。我的程序真正的目的和用处是这样的:
我用三层结构体系来传递数据,客户端程序用的是access数据库,服务端用的是oracle数据库。我想通过取出access数据库的作了更新标志字段的数据集(更新字段标志的实现是通过当用户插入或编辑一条数据时,在beforeinsert事件中值该字段为0,即为被更新的字段),通过TSocketConnect把更新数据集传递给服务端,传递采用在服务端用接口函数的方式实现,实例是在服务端创建一个 updateTotalData(Recordset1:OleVariant;KeyFieldset:widestring):widestring
stdcall;
updateTotalData实现的功能是把客户端传递的需要更新的数据集跟oracle数据库中该数据集比较,进行插入或更新。
现在问题的关键出来了:
如果数据集特别多,该函数就需要运行很久的时间,客户端调用为:socketconnect1.appserver.updateTotalData(adodataset.Recordset,'field_Id,C_sitecode');就会处于很长时间的等待,等待服务端完成更新功能,客户端在等待时,界面处于假死机状态不能移动界面。本来想在线程中处理此问题,但出现如上个回答中我提到的问题。
我现在想实现在客户端等待过程中,如果能实时得到服务端运行updateTotalData的处理进度,我就可以在客户端用application.processmessages来等待服务端完成此函数的运行了。


也研究过回调函数,研究不出什么道道来。
 
设计时没有考虑到效率的问题,现在若不改变设计,无法解决。
建议服务端使用独立的线程来处理诸如此类的长时操作,在收到客户端的更新请求后,直
接应答,然后将任务添加到任务线程的任务队列,然后由任务线程负责任务的执行,并通过
消息机制通知服务端的主线程向客户端发出完成任务的通知。
不过,至于耗时问题,我以为只能用Count之类的语句计算出参与更新的记录的数量,然
后乘适当的系数,这样能给出大致的估计值,而无法给出实际的精确进度——除非你在服务
端一行一行的执行针对单记录的Update语句,这样才能控制进度,但代价就是效率的降低。
 
Var
GlobeVar : integer;

Function TForm1.test(var varp:integer):Boolean;
var
j:integer;
begin
Result:=False;
For j:=0 to 10000 do
begin
varp:=j;
GlobeVar:=j
// 交给全局变量!
application.ProcessMessages;
end;
Result:=True;
end;
 
[brown]我喜欢creation-zy的回答,
对于madis,客户端连接服务端,服务端是创建一个Tsocketserice的线程开启连接。也就是说,我传递的socketconnect1.appserver.updateTotalData(adodataset.Recordset,'field_Id,C_sitecode');
其中的adodataset.Recordset是一个olevariant,它已经运行在此连接的线程中,当我在自定义一个线程来执行此任务时,虽然客户端不需要等待。但是问题是olevariant对象已经被主线程占有,新的自定义线程就无法取得其值,运行时只会出错,出错的大致提示是:
Eolesyserror: "应用程序调用一个已为另一线程整理的接口"。

如果哪位有兴趣。可以用Tsocketconnect在客户端建立连接,在服务端程序使用scktsvr并创建三层结构的服务端,在接口库中自定义一个函数,其中可以传递olevariant类型的参数。然后在客户端传递一个adodataset的Recordset数据集上去。
然后再在服务端的接口中定义一个线程,用来调用分析数据集。一定会出现我说的那个问题。唉,能解决此问题,我就大功告成了,但现在看来,我已经动摇了心,快决定放弃了。[/brown]
 
[green]问题不解无法安然入睡,听说olevariant参数在多个线程中调用,可以用Iinterface 马歇尔解决[/green]
 
[red]谁能帮帮,为表感谢,愿再另开300分给他。[/red]
 
顶起一下
 
大侠们,please, help
 
var改为out
 

Similar threads

S
回复
0
查看
3K
SUNSTONE的Delphi笔记
S
S
回复
0
查看
2K
SUNSTONE的Delphi笔记
S
I
回复
0
查看
778
import
I
后退
顶部