我正在开发适用于Windows Mobile 6.5,Compact Framework 3.5的应用程序。应用程序首先加载一个简单的登录表单。创建并打开登录表单时,会创建一个新线程,用于从Web Service检索某些设置数据。 3在此线程内异步调用同一Web Service。
第一个电话会检索公司列表 第二个检索属于公司的位置列表 第三个检索属于位置和用户的用户列表及其登录ID。公司
每个Web Service OnGet *** Completed事件然后将返回的数据保存到本地SQLite数据库
当我通过Visual Studio调试器编译并运行该逻辑时,一切都运行良好。应用程序启动,显示表单,创建并完成三个Web服务调用。我可以以用户身份登录并继续。好的一切都很好!
除了,当我构建我的CAB文件并在我用于调试的完全相同的设备上安装应用程序时...应用程序停留60秒并且我得到3 WebException“操作有超时”错误和应用程序被迫关闭。
我已经玩了几天并且正在研究这个问题。我阅读了很多关于在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 Service调用之前,我还将默认连接限制设置为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 Debugger顺利运行,但是当安装在MC55A Motorola设备上时,它会崩溃。该应用程序也可以在模拟器中正常运行。
我已经尝试删除1个异步Web服务调用并且它安装得非常好,但是当我尝试3个或更多时,它会失败。这几乎就像在设备上安装应用程序时一样,忽略默认连接限制并将其设置回2.
对于这部小说感到抱歉,只是想确保我提供了足够的信息,因为我在Stackoverflow上看到了类似的问题,但没有完全像这个。我确实意识到我可以同时执行这些调用同时只打开一个Web服务连接,但我们正处于紧急状态,以便为我们的客户提供最快的应用程序。即使我可以同步执行此初始同步操作,但我知道有一些地方需要同时运行2个以上的Web服务连接。
答案 0 :(得分:1)
我看到你正在捕捉并存储错误信息。你的小说恰好说出了那个错误信息是什么吗?
我还注意到你的ErrorMessage字符串值只有1项,因此可能会被覆盖。您可以尝试List(Of String)并添加错误消息......至少在您有机会发现其中一些错误之前。
在深入研究之前,您的设备可以浏览到网络服务吗?如果您的设备无法在那里浏览,那么您应用中的代码也无法访问它。
答案 1 :(得分:0)
我使用jp2code,在尝试采用代码之前,应确保设备可以连接到Web服务。
那么在调试器/仿真器中运行和在设备上独立运行之间的区别是什么:设备已连接到PC的网络。
您的设备可以连接到服务器或Web服务吗?如果没有,您的代码应该如何成功?
检查设备网络设置。它是否与工作(Windows共享)或互联网(Web浏览,Web服务)相关联?你使用WLAN还是GSM?您的网络服务是什么地址?您的网络阻止访问WLAN或公共互联网(GSM)吗?
如上所述,首先确保在更改工作代码之前连接正常。
BWT:如果设备是WLAN连接到与开发PC相同的网络,您可以通过TCP / IP使用远程调试:VS2008 remotely connect to Win Mobile 6.1 Device 使用此选项时,断开与设备的ActiveSync / WMDC连接时,您将拥有相同的环境。
答案 2 :(得分:0)
我最终创建了一个新的智能设备应用程序并尝试异步调用Web服务3次。令人惊讶的是,当我将新应用程序部署到设备时它起作用了。我慢慢地将我之前的应用程序中的代码引入到新应用程序中,到目前为止,我还无法找到其他应用程序无法正常工作的原因。 :s它们现在是完全相同的应用程序,除了新的应用程序按预期工作。
感谢您的回复,这些绝对是一个很好的起点,可以看到设备在未连接到主动同步时是否共享相同的连接。如果我发现为什么其他应用程序无法正常工作,我会发布更多信息,但截至目前新的工作正常。