InternetOpenUrl挂起并在第三次和后续调用时失败 [英] InternetOpenUrl hangs and fails on third and subsequent calls

查看:133
本文介绍了InternetOpenUrl挂起并在第三次和后续调用时失败的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是一些奇怪但可重现的行为。我可以为每个URL调用两次InternetOpenUrl,一切都按照我的预期运行。如果我在此之后再次调用它,它会在60秒内超时,并且不会返回Web资源的句柄。



我创建了以下最小代码示例来演示问题(这是对


This is some bizarre, but reproducible, behavior. I can call InternetOpenUrl exactly two times per URL and everything works as I would expect. If I call it again after that, it times out at exactly 60 seconds and does not return a handle to the web resource.

I created the following minimum code example to demonstrate the problem (this is an adaptation of the AllAPI Mentalis sample):

Private Const scUserAgent = "API-Guide test program"
Private Const INTERNET_OPEN_TYPE_DIRECT = 1
Private Const INTERNET_FLAG_RELOAD = &H80000000

Private Declare Function GetTickCount Lib "kernel32" () As Long
Private Declare Function InternetOpen _
                          Lib "wininet" Alias "InternetOpenA" _
                              (ByVal sAgent As String, ByVal lAccessType As Long, _
                               ByVal sProxyName As String, ByVal sProxyBypass As String, ByVal lFlags As Long) As Long
Private Declare Function InternetCloseHandle _
                          Lib "wininet" _
                              (ByRef hInet As Long) As Long
Private Declare Function InternetReadFile _
                          Lib "wininet" _
                              (ByVal hFile As Long, ByVal sBuffer As String, _
                               ByVal lNumBytesToRead As Long, lNumberOfBytesRead As Long) As Integer
Private Declare Function InternetOpenUrl _
                          Lib "wininet" Alias "InternetOpenUrlA" _
                              (ByVal hInternetSession As Long, ByVal lpszUrl As String, _
                               ByVal lpszHeaders As String, ByVal dwHeadersLength As Long, _
                               ByVal dwFlags As Long, ByVal dwContext As Long) As Long

Sub TestInternetOpenUrl(sURL As String)
    Dim hOpen As Long, hFile As Long, i As Integer, Start As Long
    For i = 1 To 4
        Start = GetTickCount
        'Create an internet connection
        hOpen = InternetOpen(scUserAgent, INTERNET_OPEN_TYPE_DIRECT, _
                             vbNullString, vbNullString, 0)
        'Open the url
        hFile = InternetOpenUrl(hOpen, sURL, vbNullString, ByVal 0&, _
                                INTERNET_FLAG_RELOAD, ByVal 0&)
        'clean up
        InternetCloseHandle hFile
        InternetCloseHandle hOpen
        Debug.Print i; GetTickCount - Start; " ms elapsed ("; hFile; ")"
        DoEvents
    Next i
End Sub

Here are the results of two test runs:

TestInternetOpenUrl "http://www.yahoo.com"
 1  390  ms elapsed ( 13369203 )
 2  187  ms elapsed ( 13369217 )
 3  60000  ms elapsed ( 0 )
 4  60000  ms elapsed ( 0 )

TestInternetOpenUrl "http://www.duckduckgo.com"
 1  203  ms elapsed ( 13369448 )
 2  93  ms elapsed ( 13369460 )
 3  60047  ms elapsed ( 0 )
 4  60047  ms elapsed ( 0 )

解决方案

I got this working on my end by changing how you are closing the handle. I was able to execute 30 iterations, and it worked well.

Here's the revised working code. In addition there appeared to be an issue with the API call to InternetCloseHandle (using ByRef instead of ByVal) which is corrected below:

Private Const scUserAgent = "API-Guide test program"
Private Const INTERNET_OPEN_TYPE_DIRECT = 1
Private Const INTERNET_FLAG_RELOAD = &H80000000

Private Declare Function GetTickCount Lib "kernel32" () As Long
Private Declare Function InternetOpen _
                          Lib "wininet" Alias "InternetOpenA" _
                              (ByVal sAgent As String, ByVal lAccessType As Long, _
                               ByVal sProxyName As String, ByVal sProxyBypass As String, ByVal lFlags As Long) As Long
Private Declare Function InternetCloseHandle Lib "wininet.dll" (ByVal hInet As Long) As Integer    
Private Declare Function InternetReadFile _
                          Lib "wininet" _
                              (ByVal hFile As Long, ByVal sBuffer As String, _
                               ByVal lNumBytesToRead As Long, lNumberOfBytesRead As Long) As Integer
Private Declare Function InternetOpenUrl _
                          Lib "wininet" Alias "InternetOpenUrlA" _
                              (ByVal hInternetSession As Long, ByVal lpszUrl As String, _
                               ByVal lpszHeaders As String, ByVal dwHeadersLength As Long, _
                               ByVal dwFlags As Long, ByVal dwContext As Long) As Long

Private Sub CloseHandle(ByRef hHandle As Long)
   If (hHandle <> 0) Then
        Call InternetCloseHandle(hHandle)
        hHandle = 0
    End If
End Sub

Sub TestInternetOpenUrl(sURL As String)
    Dim hOpen As Long, hFile As Long, i As Integer, Start As Long
    Dim ret As Boolean: ret = False

    For i = 1 To 4
        Start = GetTickCount
        'Create an internet connection
        hOpen = InternetOpen(scUserAgent, INTERNET_OPEN_TYPE_DIRECT, _
                             vbNullString, vbNullString, 0)
        'Open the url
        hFile = InternetOpenUrl(hOpen, sURL, vbNullString, ByVal 0&, _
                                INTERNET_FLAG_RELOAD, ByVal 0&)

        CloseHandle (hFile)
        CloseHandle (hOpen)

        Debug.Print i; GetTickCount - Start; " ms elapsed ("; hFile; ")"
        DoEvents
    Next i
End Sub

I profiled the code quickly by running this 30 times by using yahoo. Below are the relevant descriptive stats. It's taking about half a second for each call.

这篇关于InternetOpenUrl挂起并在第三次和后续调用时失败的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆