该死的Application.ProcessMessage!悬赏最高500分获得解决此方案。(100分)

  • 主题发起人 主题发起人 tomyang
  • 开始时间 开始时间
T

tomyang

Unregistered / Unconfirmed
GUEST, unregistred user!
我是一个DELPHI新手,原来都是做一些MIS项目,现在用DELPHI开发个好玩的程序,遇到
不少的困难,特请高手指点。
介绍:现在的程序是做一个Socket的Client,Client通过SOCKET发Text信息到Server。
Server根据收到的信息进行处理并且返回给CLIENT。
由于需要提供一个函数接口FUN完成整个调用的过程因此FUN1的大体是这样的:

begin
生成ID1
ClientSocket.SendText;
while ID1<>ID2 do
begin
Application.ProcessMessage;
end;
......
end;
在ClientSocket的接收事件中对id2赋值。

本来非常的简单。但是小生遇到一个问题:FUN1是提供的接口,可能同时有多人调用。
当调用1没有被ServerSocket处理完就来了调用2时调试发现ID2是调用1的ID2从而得不
到结果。

不知道为什么调用1的函数没有继续判断ID呢?我怀疑是Application.ProcessMessage
的问题,为什么会有此问题呢?哪位大侠有谢绝的思路?
如果能够用多线程解决此问题请给出详细的解决方法。

最给有500分,如果您觉得不过我一共有695分。
 
sorry,有很多错字,重贴

我是一个DELPHI新手,原来都是做一些MIS项目,现在用DELPHI开发个好玩的程序,遇到
不少的困难,特请高手指点。
介绍:现在的程序是做一个Socket的Client,Client通过SOCKET发Text信息到Server。
Server根据收到的信息进行处理并且返回给CLIENT。
由于需要提供一个函数接口FUN完成整个调用的过程因此FUN1的大体是这样的:

begin
生成ID1
ClientSocket.SendText;
while ID1<>ID2 do
begin
Application.ProcessMessage;
ID2='';
end;
......
end;
在ClientSocket的接收事件中对id2赋值。

本来非常的简单。但是小生遇到一个问题:FUN1是提供的接口,可能同时有多人调用。
当调用1没有被ServerSocket处理完就来了调用2时,调试发现ID2是调用1的ID2从而得不
到结果。

不知道为什么调用1的函数没有继续判断ID呢?我怀疑是Application.ProcessMessage
的问题,为什么会有此问题呢?哪位大侠有谢绝的思路?

如果能够用多线程解决此问题请给出详细的解决方法(小生是新手^_^懂一点,但不多)。

最多有500分,如果您觉得不够我一共有695分。
 
高手请发话,在下洗耳恭听
 
写得不够清楚,ID1/2是全局变量?
你调试到
ID2='';
时情况到底如何?
按现有的代码来看,似乎有逻辑问题:
WHILE循环后ID2总是会变空串,
这样其实你的代码等价于:

WHILE ID2<>'' DO //注意此句!
BEGIN
ID2='';
END;

这样循环一次后就肯定ID2=''了.这样应该使用IF语句才合理嘛!

如果是这样:
WHILE ID2<>'任意非空字串' DO
BEGIN
ID2='';
END
//成死循环了.
 
如果你安装的是delphi3.0,你可以在
C:/Program Files/Borland/Delphi 3/Demos/INTERNET/CHAT/
以及
C:/Program Files/Borland/Delphi 3/Demos/INTERNET/TCP/
找到两个很好的例子!

 
wint大侠:
ID1是一个局部变量,我每次socket.sendtext时生成一个ID并与需要Send的text一同
发出到Server端,Server处理有返回的串中有也有ID。ClientSocket接收到后获得ID并存储
在ID2中。可以说ID2是一个全局变量。
在对他的跟踪好象没有找到太好的办法,因为在FUN1的第一次调用还没有调试完毕,另一次
又开始了。我的ID是下面的格式:
'*******1'
'*******2'
'*******3'
.....
如果一次接一次的调用FUN1则能够正确的工作EVERYTHING IS FINE。但是如果调用的频率比较
的频繁,那么则无法收到结果。设一断点跟踪发现ID1='******15',ID2='******11'。因此
主要集中在如何调用函数上。我想第11次调用FUN1时FUN1还没有执行完,他执行到什么地方
去了?否则应当处理'******11'呀!我想改用多线程处理此问题,但不得门路。
希望大侠拉我一把,必将涌分相报。

to thtfsyh英雄:
谢谢指点。但是小生的问题不在于此。请再费力气帮助小生。
 
高手快来,如果看不明白请提出来。
救命呀!太阳出来了,太热了,快开空调呀!
 
这个这个。。。。怪怪的。
我救不了。
 
本人有一种想法:
好象确实没有办法实现。但是我实际上是做一个类并注册,在.ASP中可以调用。如果是在
.asp中调用恐怕没有这样的错误发生。上面的错误之所以发生可能是因为调用FUN1是在测试
的button中触发。我将进一步进行测试一下,估计下周有一个明确的答案(希望有)。

winnt:谢谢你。希望能够再死几个脑细胞以解救我于水深火热中。

大虾!就此发表一些看法,给我一些IDEAS吧!
 
试一下 socket.Lock;socket.unlock,看行不行。
 
tomyang:
没办法了,这就是我的水平了。
 
希望你再说清楚一些!

另:

ID2的获得是在接收事件中获得,但此事件是应该由窗口消息触发的(根据Winsock SDK )

所以,只有在你调用了Application.ProcessMessage后,ID2才能被赋制,但你又把

ID2清空了,我手头没有delphi,比较迷惑。。。
 
我也听听..........
 
你干吗不将其封到线程中呢?
 
恕我愚昧,Application.ProcessMessage;是干嘛的?
我最近也在写一个c/s socket的程序,好像没碰到什么问题
服务端监听,客户端接收,有什么问题吗?
说实话,我看不太懂你的问题
fun1是要给多人同时调用的吗?
为什么不把fun1放在客户端运行呢?
我的看法是把可能的部分放在客户端,服务端只负责传递数据和进行简单判断。
 

to Aiirii:
谢谢你的提议,但是好象不能解决。

to thtfsyh:
请不要放弃,我已经从这个问题中找到了乐趣。^_^ Never Give Up!

to hustmouse:
You are right!至于ID2它不过是一个标识,表示ID为ID2的socket已经返回。在FUN1中判断
到后与其ID1相同的数据出现后将继续处理,否则等待。因为我要实现的流程是:client发送-
server接受-server处理-server发送-client接收-client处理-end。FUN1在CLIENT端。

to ArJianzeng:
各个,弟弟非常的烦恼,您老人家不能就在旁边看着呀!提一些建议吧!

to liguang:
本人也有此想法,无奈对多线程不是特别的了解,没有太多的头绪。关键在于SOCKET的发送
后需要等待并接收。如果将等待做成多线程,在FUN1中必须TThread.wait,而TThread.wait
并不释放对主线程的调用还是要调用application.processmessage.没有太好的办法。你老
人家有方法吗?

to 小猪:
application.processmessage我也不是特别的了解,仅仅知道他能够释放主线程。FUN1并不
是由最终由于调用。我想编写一个DLL类,在ASP中可以调用。在类的一个函数中调用FUN1。
因此不能把FUN1放到最终用户的桌面上。

各位英雄:我刚刚用DELPHI,就碰到这样的问题,我冤呀!我tmd比窦娥还冤!看天边漂过
一片乌云。要下雪了,快收衣服呀!各位晴天大老爷,为我伸冤呀!!!!!!!!!!
 
高手,高手,又见高手!
高手快来!!!!!!!

不一定要给出源码,给点IDEA就行!

时代呼唤高手!
 
在这个地方有使用
application.processmessage 的必要么?,去掉的话有什么影响??

application.processmessage 只是让系统去执行一些其它的事件信息,比如你在做一个
长时间的循环时,你的程序几呼处于死掉的形态中,而如果你在循环中插入这样一句语
句的话,你会发现你能移动Form,甚至执行其它的按钮事件。

当然,如果你的其它事件的操作有影响到这个循环中的变量什么的,那么完全可能会导
致当前循环执行出错,严重的造成系统崩溃

一般情况下application.processmessage 可以不用,你不用试试看了,行了再加上试试

 
to fatbaby:
thank you for your join!抱歉没有找到不用application.processmessage 的方法。虽然
我也感觉都是application.processmessage惹的货。首先在fun1中完成sendtext后需要等
回应,在等待的过程中必须释放delphi的主进程以确认clientsocket的事件能够被触发,
各个:你有别的方法吗?
 
我觉得,从你的程序看来,clientsocket是在主线程中创建的,
因此,即使在clientsocket的接收事件中给ID2赋值标识ID2的ID已经
返回,但他们实际在一个线程中,因此,在Application.Procmessage后
的代码ID2:=''又将ID2赋值为空了(clientsocket的接收事件是由
Application.procmessage处理的)

你应该将他单独封装到一个线程中去,然后使用事件通知

SetEvent

WaitForSingleObject ( or WaitForMutipleObjects )
 
后退
顶部