none
关于webclient的问题,第一次引用实例时会阻塞窗体线程 RRS feed

  • 问题

  • 为了让访问网络不阻塞界面,以提高用户体验,我使用了异步网络请求。但有一个问题我百思不得解,故来此求教:

    异步请求是正常的,执行之后,界面不会阻塞,点击拖动界面也不会出现“未响应”之类的话。但软件启动后,第一次发出联网请求时,却是阻塞的。我在webclient.uploadstringasync()语句执行前和后,以及提交完成的事件过程里都放了debug.now()来测试时间,发现就是第一次使用的时候,界面卡住约有6,7秒以上那样子,而事件返回的都只有1,两秒(正确返回)。

    而我之前好像也遇到这个问题,并且在做应用时曾用封包监视工具查看,发现那阻塞的几秒时间里,并没用进行网络提交。也就是,webclient的第一次引用并不是立即的,我想清楚,它在干嘛,为什么阻塞,如何避免?

    谢谢。


    学无目的
    2011年9月6日 0:35

答案

  • 您好,感谢你的回复。(上面的代码我不知道如何去测试...抱歉)

    我的问题我进行了多次试验,我发现两个特点:

    1,我测试的延迟就是14秒。(从对象开始执行方法起,到数据返回。)

    2,只在软件第一次联网时产生这样的延迟。而后的联网操作,都非常快。

    以上所说的联网都指向web服务器发送http请求。

     

    网上没有查到有关的详细资料。不知道是不是DNS等问题。

     

    恳请指点详情。如果这是不可避免的,那教如何替换这样的方法,以提高软件的用户体验。谢谢

     


    学无目的
    我好像已经找到问题了,这真是个隐蔽的问题,在网上看到一篇问题一样的文章,原来是默认proxy开启的原因使联网处于proxy等待中。将proxy设为nothing就明显改善了我所描述的问题。

    学无目的
    2011年9月16日 15:24
  • Hi ,

    这是该方法的源码, 你可以继续测试下是哪步耗费了太长的时间:

    <HostProtection(SecurityAction.LinkDemand, ExternalThreading:=True)> _
    Public Sub UploadStringAsync(ByVal address As Uri, ByVal method As String, ByVal data As String, ByVal userToken As Object)
        If Logging.On Then
            Logging.Enter(Logging.Web, Me, "UploadStringAsync", address)
        End If
        If (address Is Nothing) Then
            Throw New ArgumentNullException("address")
        End If
        If (data Is Nothing) Then
            Throw New ArgumentNullException("data")
        End If
        If (method Is Nothing) Then
            method = Me.MapToDefaultMethod(address)
        End If
        Me.InitWebClientAsync
        Me.ClearWebClientState
        Dim asyncOp As AsyncOperation = AsyncOperationManager.CreateOperation(userToken)
        Me.m_AsyncOp = asyncOp
        Try 
            Dim bytes As Byte() = Me.Encoding.GetBytes(data)
            Me.m_Method = method
            Me.m_ContentLength = bytes.Length
            Dim request As WebRequest = Me.m_WebRequest = Me.GetWebRequest(Me.GetUri(address))
            Me.UploadBits(request, Nothing, bytes, 0, Nothing, Nothing, New CompletionDelegate(AddressOf Me.UploadStringAsyncWriteCallback), New CompletionDelegate(AddressOf Me.UploadStringAsyncReadCallback), asyncOp)
        Catch exception As Exception
            If ((TypeOf exception Is ThreadAbortException OrElse TypeOf exception Is StackOverflowException) OrElse TypeOf exception Is OutOfMemoryException) Then
                Throw
            End If
            If (Not TypeOf exception Is WebException AndAlso Not TypeOf exception Is SecurityException) Then
                exception = New WebException(SR.GetString("net_webclient"), exception)
            End If
            Me.UploadStringAsyncWriteCallback(Nothing, exception, asyncOp)
        End Try
        If Logging.On Then
            Logging.Exit(Logging.Web, Me, "UploadStringAsync", CStr(Nothing))
        End If
    End Sub
    
    Best regards,

     


    Mike Feng [MSFT]
    MSDN Community Support | Feedback to us
    Get or Request Code Sample from Microsoft
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    2011年9月11日 8:22
    版主

全部回复

  • 一天了没人帮我,是这个问题太简单了吗?还是没有人遇到过,急切啊。。。
    学无目的
    2011年9月6日 12:20
  • Hi ,

    这是该方法的源码, 你可以继续测试下是哪步耗费了太长的时间:

    <HostProtection(SecurityAction.LinkDemand, ExternalThreading:=True)> _
    Public Sub UploadStringAsync(ByVal address As Uri, ByVal method As String, ByVal data As String, ByVal userToken As Object)
        If Logging.On Then
            Logging.Enter(Logging.Web, Me, "UploadStringAsync", address)
        End If
        If (address Is Nothing) Then
            Throw New ArgumentNullException("address")
        End If
        If (data Is Nothing) Then
            Throw New ArgumentNullException("data")
        End If
        If (method Is Nothing) Then
            method = Me.MapToDefaultMethod(address)
        End If
        Me.InitWebClientAsync
        Me.ClearWebClientState
        Dim asyncOp As AsyncOperation = AsyncOperationManager.CreateOperation(userToken)
        Me.m_AsyncOp = asyncOp
        Try 
            Dim bytes As Byte() = Me.Encoding.GetBytes(data)
            Me.m_Method = method
            Me.m_ContentLength = bytes.Length
            Dim request As WebRequest = Me.m_WebRequest = Me.GetWebRequest(Me.GetUri(address))
            Me.UploadBits(request, Nothing, bytes, 0, Nothing, Nothing, New CompletionDelegate(AddressOf Me.UploadStringAsyncWriteCallback), New CompletionDelegate(AddressOf Me.UploadStringAsyncReadCallback), asyncOp)
        Catch exception As Exception
            If ((TypeOf exception Is ThreadAbortException OrElse TypeOf exception Is StackOverflowException) OrElse TypeOf exception Is OutOfMemoryException) Then
                Throw
            End If
            If (Not TypeOf exception Is WebException AndAlso Not TypeOf exception Is SecurityException) Then
                exception = New WebException(SR.GetString("net_webclient"), exception)
            End If
            Me.UploadStringAsyncWriteCallback(Nothing, exception, asyncOp)
        End Try
        If Logging.On Then
            Logging.Exit(Logging.Web, Me, "UploadStringAsync", CStr(Nothing))
        End If
    End Sub
    
    Best regards,

     


    Mike Feng [MSFT]
    MSDN Community Support | Feedback to us
    Get or Request Code Sample from Microsoft
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    2011年9月11日 8:22
    版主
  • 您好,感谢你的回复。(上面的代码我不知道如何去测试...抱歉)

    我的问题我进行了多次试验,我发现两个特点:

    1,我测试的延迟就是14秒。(从对象开始执行方法起,到数据返回。)

    2,只在软件第一次联网时产生这样的延迟。而后的联网操作,都非常快。

    以上所说的联网都指向web服务器发送http请求。

     

    网上没有查到有关的详细资料。不知道是不是DNS等问题。

     

    恳请指点详情。如果这是不可避免的,那教如何替换这样的方法,以提高软件的用户体验。谢谢

     


    学无目的
    2011年9月16日 12:54
  • 您好,感谢你的回复。(上面的代码我不知道如何去测试...抱歉)

    我的问题我进行了多次试验,我发现两个特点:

    1,我测试的延迟就是14秒。(从对象开始执行方法起,到数据返回。)

    2,只在软件第一次联网时产生这样的延迟。而后的联网操作,都非常快。

    以上所说的联网都指向web服务器发送http请求。

     

    网上没有查到有关的详细资料。不知道是不是DNS等问题。

     

    恳请指点详情。如果这是不可避免的,那教如何替换这样的方法,以提高软件的用户体验。谢谢

     


    学无目的
    我好像已经找到问题了,这真是个隐蔽的问题,在网上看到一篇问题一样的文章,原来是默认proxy开启的原因使联网处于proxy等待中。将proxy设为nothing就明显改善了我所描述的问题。

    学无目的
    2011年9月16日 15:24