0

我正在为 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 服务的配置中设置 Max Connection 的内容,并且我还将绑定设置为较大的值,如下所示:

<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 服务连接。

4

3 回答 3

1

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

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

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

于 2013-09-13T19:12:16.137 回答
0

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

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

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

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

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

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

于 2013-09-14T04:24:21.820 回答
0

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

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

于 2013-09-16T12:54:56.973 回答