200分:对一个API说明的疑问(200分)

  • 主题发起人 主题发起人 monster
  • 开始时间 开始时间
M

monster

Unregistered / Unconfirmed
GUEST, unregistred user!
************************ &nbsp; DWORD RasHangUp(HRASCONN hrasconn); &nbsp;**********************<br>The connection is terminated even if the RasDial call has not yet been completed.<br>After this call, the hrasconn handle can no longer be used. <br>An application should not call RasHangUp and then immediately exit. The connection<br>state machine needs time to properly terminate. If the system prematurely terminates<br>the state machine, the state machine may fail to properly close a port, leaving the<br>port in an inconsistent state. A simple way to avoid this problem is to call <br>Sleep(3000) after returning from RasHangUp; after that pause, the application can <br>exit. A more responsive way to avoid the problem is, after returning from RasHangUp,<br>to call RasGetConnectStatus(hrasconn) and Sleep(0) in a loop until RasGetConnectStatus<br>returns ERROR_INVALID_HANDLE<br>************************ &nbsp; DWORD RasHangUp(HRASCONN hrasconn); &nbsp;**********************<br>照此说明,调用RasHangUp后,程序不应该立即退出,需要给出时间以正常关闭,以免端口状态不一致.<br>最好是在一个循环里反复调用RasGetConnectStatus(hrasconn),直到返回ERROR_INVALID_HANDLE为止.<br>由此,我写出如下代码:<br>&nbsp; //初始化RasConnStatus结构<br>&nbsp; FillChar(RasConnStatus,SizeOf(RasConnStatus),0);<br>&nbsp; RasConnStatus.dwSize:=SizeOf(TRasConnStatus);<br><br>&nbsp; dw := RasHangUp(AHandle);<br>&nbsp; //成功,也不能立即返回,要等待关闭端口<br>&nbsp; if dw = 0 then<br>&nbsp; begin<br>&nbsp; &nbsp; //一直等到出现非法句柄为止<br>&nbsp; &nbsp; while RasGetConnectStatus(AHandle, RasConnStatus) &lt;&gt; &nbsp;ERROR_INVALID_HANDLE do<br>&nbsp; &nbsp; begin<br>&nbsp; &nbsp; &nbsp; Sleep(0);<br>&nbsp; &nbsp; &nbsp; //Application.ProcessMessages;<br>&nbsp; &nbsp; end;<br>&nbsp; end;<br>结果如下:<br>&nbsp; &nbsp; 1.完全连接成功时执行RasHangUp,第一次调用RasGetConnectStatus就得到ERROR_INVALID_HANDLE,<br>一切正常;<br>&nbsp; &nbsp; 2.在连接过程中执行RasHangUp,就陷入了死循环,每次调用RasGetConnectStatus都得到执行时的状<br>态!!!死翘翘了.<br>&nbsp; &nbsp; 3.我若去掉while循环判断,程序随时挂断都没有任何问题出现,难道微软的文档是在自找麻烦?
 
且看TurboPower_Apro控件中的TApdRasDialer的方法:<br><br>&nbsp; AdRasHangup(Connection);<br>&nbsp; FConnection := 0;<br>&nbsp; while (AdRasHangup(FConnection) &lt;&gt; ERROR_INVALID_HANDLE) do<br>&nbsp; &nbsp; Sleep(0); &nbsp; &nbsp; &nbsp;<br><br>要不他们觉着RasGetConnectStatus不行,反复用AdRasHangup也好说.<br>这叫啥呀? 把FConnection := 0了,再拿它去传给AdRasHangup(注意:不是RasGetConnectStatus),<br>不得到ERROR_INVALID_HANDLE才怪呢!<br>
 
再看TDialUp的HangUp实现:<br>&nbsp; FillChar(Stat, Sizeof(TRasConnStatus), 0);<br>&nbsp; Stat.dwSize:=Sizeof(TRasConnStatus); // Must be zeroed and sized<br>&nbsp; Result:=RasHangUp(Handle);<br><br>&nbsp; if( result&lt;&gt;0 )then exit ;<br><br>&nbsp; while (RasGetConnectStatus(handle,stat)&lt;&gt;ERROR_INVALID_HANDLE) do<br>&nbsp; begin<br>&nbsp; &nbsp; Sleep(0);<br>&nbsp; &nbsp; Application.ProcessMessages;<br>&nbsp; end; // Wait actual closure, else port could remain locked<br><br>我采用了这种方法(加上Application.ProcessMessages;)后, 在连接过程中中断倒也<br>不再是获得执行RasHangUp前的状态了,自始至终都是RASCS_Disconnected(未连接)状态,<br>程序也退不出来了!!!我的程序里有一个消息处理函数,这是和TDialUp不一样的地方,我<br>猜想可能因为这个,TDialUp可以, 我的这样就不行.<br><br><br>
 
2.在连接过程中执行RasHangUp,就陷入了死循环,每次调用RasGetConnectStatus都得到执行时的状<br>态!!!死翘翘了.<br>&nbsp; &nbsp; <br>TDialup比你多了一句:<br>&nbsp; &nbsp;if( result&lt;&gt;0 )then exit ;<br><br>也就是说他在rashangup不成功时会退出。是不是有可能你在连接过程中rashangup不成功所以<br>RasGetConnectStatus都得到执行时的状态总是连接的??<br><br>3.我若去掉while循环判断,程序随时挂断都没有任何问题出现,难道微软的文档是在自找麻烦?<br><br>他是为了确保成功!这样多执行几行代码以换取安全。<br>
 
sonie:<br>&nbsp; &nbsp; 大哥,你看我也多了一句:<br>&nbsp; &nbsp; if dw = 0 then<br>&nbsp; &nbsp; 所以我是在rashangup成功才这么干的.<br>&gt;&gt;他是为了确保成功<br>&nbsp; &nbsp; 嗨,唯一的问题恐怕是rashangup以后马上rasdial,会告诉你"端口已经打开",不过一点问题也没有,<br>过两秒钟就可以了.<br>&nbsp; &nbsp; 可能会试用<br>"A simple way to avoid this problem is to call <br>Sleep(3000) after returning from RasHangUp"<br>&nbsp; &nbsp; 哈哈,程序不过慢点响应罢了,"端口已经打开"的错误少出现点, 还不如啥处理都不作给人的感觉快,爽!<br><br>&nbsp; &nbsp; 我要一种好的解决方案!<br>&nbsp; &nbsp; 谢谢大家!<br>
 
对不起看漏了if dw=0...这句。<br><br>你试着在此时(rashangup成功,你有程序死循环时)再用另一个程序去试试端口?看它是不是还忙?<br>如果忙,要么就是rashangup不成功,要么就是你不够耐心还可以等,当然也可能是RasGetConnectStatus有问题了<br>。如果不忙了,hehe,那就几乎可以肯定是RasGetConnectStatus有问题了。<br><br><br>另我想,这个方案可能是比较恰当的了,sleep(3000)显然是不到万不得已谁也不会采用的一种方案了,不仅耗时也不见得<br>安全(3秒内没关掉)。<br><br>
 
我也碰到过这个问题,关注
 
高手们都发发意见,不要只关注,谢谢:)
 
加分加分加分加分加分加分加分加分!!!
 
大虾呀,帮帮忙吧:(
 
看的人是直线上升(我5分钟往前刷一次阿),可就是没人理我呀。<br>昨天去Borland的新闻组问这个问题,被老外一顿涮,丢人啊:(<br>大家帮帮我呀。<br>有一位仁兄说是在stat中的dwError里才会出现ERROR_INVALID_HANDLE,可我的测试说明<br>RasGetConnectStatus(handle,stat)能够直接返回ERROR_INVALID_HANDLE。。。
 
根据帮助文件,确实用stat才是对的
 
Pipi.兄说的是那个帮助文件?望明示。<br>我在实际的测试中,发现<br>  dw := RasGetConnectStatus(handle,stat)<br>中,真正未连接时(彻底断开),dw是6(即Error_INvalid_Handle),而stat.dwError的值此时为0<br>在其他情况下,stat.dwError的之可能是600(操作待处理),630等,从未发现为6.<br>不知那位好心人也试过?
 
faint,我现在才看到你把Application.ProcessMessages注释了,这句注释不得!!!<br>一但注释就没有一点延时了。<br><br>要么就不注释这句,要么就sleep一个指定时间。(当然用消息轮循的方式更实时)
 
大哥,我的第三贴对此已经有所说明.TDialUp里这么用,我这么用却不行,我也不知为什么.<br>另外,<br>repeat<br>&nbsp; Sleep(100);<br>until xxxx<br>的方式我一试过,不行,所以jedi的示例里,一是判断状态,二是看是否超时,二者满足其一,<br>就退出.恐怕他们也发现只循环不好使, 有这么个条件只是证明'我们兼容MS说明':)
 
那你就照jedi的示例做吧:)
 
谢谢sonie兄在几个贴子里的关注!
 
后退
顶部