【问题标题】:windows mobile .net CF 3.5 Multiple Async Web Service Calls = Timeoutwindows mobile .net CF 3.5 多个异步 Web 服务调用 = 超时
【发布时间】:2013-09-17 07:49:08
【问题描述】:

我正在开发适用于 Windows Mobile 6.5、Compact Framework 3.5 的应用程序。该应用程序首先加载一个简单的登录表单。在创建并打开登录表单时,会创建一个新线程来从 Web 服务中检索一些设置数据。 3 在这个线程中异步地对同一个 Web 服务进行单独的调用。

第一个调用检索公司列表 第二个检索属于公司的位置列表 第三个检索属于某个位置和公司的用户列表及其登录 ID

每个 Web Service OnGet***Completed 事件然后将返回的数据保存到本地 SQLite 数据库

当我通过 Visual Studio 调试器编译和运行该逻辑时,一切运行良好。应用程序启动,显示表单,创建并完成三个 Web 服务调用。我可以以用户身份登录并继续。好的,一切都很好!

除了,当我构建我的 CAB 文件并将应用程序安装在我用于调试的完全相同的设备上时...应用程序等待 60 秒,我得到 3 WebException "The operation has timed-out" 错误和应用程序被强制关闭。

这几天我一直在玩和研究这个问题。我阅读了很多关于在 Web 服务的配置中设置最大连接的内容,并且我还将绑定设置为较大的值,如下所示:

<add address="*" maxconnection="324"/>  

<binding name="BasicHttpBinding_IGenericContract" closeTimeout="00:01:00"
        openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00"
        allowCookies="false" bypassProxyOnLocal="false" hostNameComparisonMode="StrongWildcard"
        maxBufferSize="2147483647" maxBufferPoolSize="2147483647" maxReceivedMessageSize="2147483647"
        messageEncoding="Text" textEncoding="utf-8" transferMode="Buffered"
        useDefaultWebProxy="true">
      <readerQuotas maxDepth="2147483647" maxStringContentLength="2147483647" maxArrayLength="2147483647"
          maxBytesPerRead="2147483647" maxNameTableCharCount="2147483647" />
    </binding>

在 Windows Mobile 应用程序中启动 Web 服务调用之前,我还将默认连接限制设置为 22。

这是我的代码,它通过创建每个类的新实例来启动所有三个异步 Web 服务调用(类结构如下所示)

 'Currently Inside of Initial Synchronize Thread
 System.Net.ServicePointManager.DefaultConnectionLimit = 22
 Dim syncCompanies As New SyncCompanies(True)
 Dim syncLocations As New SyncLocations(True)
 Dim syncUsers As New SyncUsers(True)

这里是 SyncCompanies 类 New 方法接受一个“异步”布尔参数,该参数告诉类异步或同步执行 Web 服务调用。我想异步运行所有三个 Web 服务。

Public Class SyncCompanies
Private service As New RDScanService.BasicHttpBinding_IGenericContract

'Method that Retrieves the Companies data from the server
Public Sub New(ByVal Asynchronous As Boolean)
    DoAsynchronously = Asynchronous
    NewCompanies = New Companies(False, False)

    Try
        IsBusy = True

        If DoAsynchronously Then
            'Begin the Asynchronous Call
            Dim cb As New AsyncCallback(AddressOf onGetCompaniesComplete)
            service.BeginGetCompanies(currentSetup.LastCompaniesSync, True, cb, Nothing)
        Else
            'Perform the Synchronous Call, create a list of Companies and pass to the Execute function for saving
            For Each company In service.GetCompanies(currentSetup.LastCompaniesSync, True)
                Dim newCompany As New Company(False, False, "")

                newCompany.Code = company.Code
                newCompany.ReportName = company.ReportName

                NewCompanies.Companies.Add(newCompany)
            Next

            Execute()
            IsBusy = False
        End If
    Catch ex As Exception
        service.Abort()
        IsBusy = False
        Success = False
        ErrorVerb = "retrieving companies from server"
        ErrorMessage = ex.Message
    Finally
        Dispose()
    End Try
End Sub

Private Sub onGetCompaniesComplete(ByVal ar As IAsyncResult)
    'End the Asynchronous Web Service Call and start the Asynchronous Processing
    For Each company In service.EndGetCompanies(ar)
        Dim newCompany As New Company(False, False, "")

        newCompany.Code = company.Code
        newCompany.ReportName = company.ReportName

        NewCompanies.Companies.Add(newCompany)
    Next

    ExecuteAsync()
End Sub

Public Sub ExecuteAsync()
    'Run the Synchronous method on a new ThreadPool thread
    ThreadPool.QueueUserWorkItem(AddressOf DoExecute)
End Sub

Public Sub Execute()
    'First determine if the Web Service returned any Companies to save...
    If NewCompanies.Companies.Count > 0 Then
        NewCompanies.SubmitToDB(True)

        If NewCompanies.Success Then
            Success = True
        Else
            Success = False
            ErrorVerb = "syncing companies"
            ErrorMessage = NewCompanies.Message
        End If
    End If

    IsBusy = False
End Sub

Private Sub DoExecute(ByVal stateInfo As Object)
    'Call the Synchronous method on this ThreadPool thread
    Execute()
End Sub

Private _newCompanies As Companies
Public Property NewCompanies() As Companies
    Get
        Return (_newCompanies)
    End Get
    Set(ByVal value As Companies)
        _newCompanies = value
    End Set
End Property

Private _success As Boolean
Public Property Success() As Boolean
    Get
        Return (_success)
    End Get
    Set(ByVal value As Boolean)
        _success = value
    End Set
End Property

Private _errVerb As String
Public Property ErrorVerb() As String
    Get
        Return (_errVerb)
    End Get
    Set(ByVal value As String)
        _errVerb = value
    End Set
End Property

Private _errMessage As String
Public Property ErrorMessage() As String
    Get
        Return (_errMessage)
    End Get
    Set(ByVal value As String)
        _errMessage = value
    End Set
End Property

Private _isBusy As Boolean
Public Property IsBusy() As Boolean
    Get
        Return (_isBusy)
    End Get
    Set(ByVal value As Boolean)
        _isBusy = value
    End Set
End Property

Private _doAsynchronously As Boolean
Public Property DoAsynchronously() As Boolean
    Get
        Return (_doAsynchronously)
    End Get
    Set(ByVal value As Boolean)
        _doAsynchronously = value
    End Set
End Property

Protected Sub Dispose()
    service.Dispose()
End Sub

结束类

对于我来说,无法弄清楚为什么我的应用程序可以顺利通过 Visual Studio 调试器运行,但是当安装在 MC55A 摩托罗拉设备上时,它会崩溃。该应用程序在模拟器中也可以正常运行。

我已尝试删除 1 个异步 Web 服务调用,安装时效果很好,但是当我尝试 3 个或更多时,它失败了。几乎就像在设备上安装应用程序时,默认连接限制被忽略并设置回 2。

对小说感到抱歉,我只是想确保我提供了足够的信息,因为我在 Stackoverflow 上看到过类似的问题,但没有与这个完全一样的问题。我确实意识到我可以在一次只打开 1 个 Web 服务连接的情况下同步执行这些调用,但是我们急需使这个应用程序对我们的客户来说是最快的。尽管我可以同步执行此初始同步操作,但我知道在某些地方我需要同时运行 2 个以上的 Web 服务连接。

【问题讨论】:

    标签: vb.net web-services asynchronous windows-mobile compact-framework


    【解决方案1】:

    我看到您正在捕获并存储错误消息。你的小说有没有碰巧说那个错误信息是什么?

    我还注意到您的 ErrorMessage 字符串值只有 1 项,因此它可能会被覆盖。您可以尝试 List(Of String) 并添加错误消息...至少在您有机会捕获其中一些错误之前。

    在深入探讨之前,您的设备可以浏览到网络服务吗?如果您的设备无法浏览那里,那么您的应用程序中的代码也将无法访问它。

    【讨论】:

    • 感谢回复,错误返回给调用这些类的主函数。如果发生错误,则会显示出来。出于某种原因,尽管此代码不会产生 try catch 错误。当我实施超时检查时,我抓住了它。错误信息也在小说中是的,哈哈。我可以通过网络浏览器连接到该服务。此外,我尝试创建一个全新的应用程序,立即调用该服务三遍,并且成功了。慢慢的把代码拿进来了,也查不出原来的App为什么会出现这个问题。
    【解决方案2】:

    我同意 jp2code,在尝试采用该代码之前,您应该确保设备可以连接到 Web 服务。

    那么在调试器/模拟器中运行和在设备上独立运行之间的区别是什么:设备已连接到您 PC 的网络。

    您的设备可以连接到服务器或网络服务吗?如果没有,你的代码应该如何成功?

    检查设备网络设置。它是否连接到工作(Windows 共享)或互联网(网络浏览、网络服务)?您使用 WLAN 还是 GSM?您的网络服务是什么地址?您的网络是否阻止了 WLAN 或公共互联网 (GSM) 的访问?

    如前所述,在更改您的工作代码之前,首先确保连接正常。

    BWT:如果设备是 WLAN 连接到与开发 PC 相同的网络,您可以通过 TCP/IP 使用远程调试:VS2008 remotely connect to Win Mobile 6.1 Device 使用它,当您断开与设备的 ActiveSync/WMDC 连接时,您将拥有相同的环境。

    【讨论】:

    • 我有设备严格使用我们在这里设置的无线接入点,不管它是否插入。前几天我尝试的是创建一个全新的应用程序并在没有任何其他代码的情况下进行 3 次 Web 服务调用。它奏效了,我慢慢地将我以前的应用程序中的代码带到了这个应用程序中。我找不到其他应用程序无法运行的原因。
    【解决方案3】:

    我最终创建了一个新的智能设备应用程序,并尝试连续 3 次异步调用 Web 服务。令人惊讶的是,当我将新应用程序部署到设备时它起作用了。我慢慢地将我以前的应用程序中的代码引入到新应用程序中,到目前为止,我还没有找到其他应用程序无法运行的原因。 :s 它们现在是完全相同的应用程序,除了新的应用程序按预期工作。

    感谢您的回复,这些绝对是查看设备在未连接到活动同步时是否共享同一连接的良好起点。如果我发现其他应用程序无法运行的原因,我会发布更多信息,但到目前为止,新应用程序运行良好。

    【讨论】:

      猜你喜欢
      • 2012-05-29
      • 1970-01-01
      • 2010-10-19
      • 2015-07-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-10-27
      • 1970-01-01
      相关资源
      最近更新 更多