Question

I'm developing an App for Windows Mobile 6.5, Compact Framework 3.5. The application starts by loading a simple login form. While the login form is created and opening, a new thread is created for retrieving some setup data from a Web Service. 3 Separate calls are made to the same Web Service asynchronously within this thread.

The first call retrieves a list of Companies The second retrieves a list of Locations that belong to a Company The third retrieves a list of Users and their Login ID's that belong to a Location & Company

Each Web Service OnGet***Completed event then saves the returned data to a local SQLite Database

When I compile and run that logic through the Visual Studio debugger, everything runs great. The app starts, the form is shown, the three web service calls are created and finish. I can login as a user and carry on. Ok all is good!

EXCEPT, when I build my CAB file and install the application on the exact same device I use for debugging... the application sits for 60 seconds and I get 3 WebException "The operation has timed-out" errors and the application is forced closed.

I've been playing and researching this issue for a couple of days now. I read a lot about setting the Max Connection in the config of the Web Service and I have also set the bindings to be large values as shown below:

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

and

<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>

I have also set the Default Connection Limit to 22 before I start the Web Service calls in the Windows Mobile application.

Here is my code that starts all three asynchronous Web Service calls by creating new instances of each class (class structure shown below)

 '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)

Here is the SyncCompanies class The New method accepts a "Asynchronous" boolean parameter which tells the class to Execute the Web Service call asynchronously or synchronously. I would like to run all three web services asynchronously.

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

End Class

For the life of me, can't figure out why my application runs smoothly through the Visual Studio Debugger, but when installed on the MC55A Motorola device, it crashes. The application also runs fine in the emulator.

I have tried removing 1 of the Asynchronous Web Service calls and it worked perfectly fine installed, but when I try 3 or more, it fails. It is almost like when the application is installed on the device, the Default Connection Limit is ignored and set back to 2.

Sorry for the novel, just wanted to make sure I gave enough information since I have seen similar issues on Stackoverflow, but nothing exactly like this one. I do realize that I could perform these calls Synchronously with only 1 Web Service connection open at a time, but we are in a crunch to make this application the fastest for our customers. Even though I can perform this Initial Sync operation synchronously, I know there will be places down the road where I need more than 2 web service connections running at once.

Was it helpful?

Solution 3

I ended up creating a new Smart Device Application and tried calling the web service 3 times in a row asynchronously. Surprisingly it worked when I deployed the new app to the device. I slowly brought in the code from my previous app into the new one and so far I have not been able to find why the other app wasn't working. :s They are now the exact same applications except the new one works as expected.

Thanks for the responses, those were definitely good starting points to see if the device was sharing the same connection when not connected to active sync. I will post up further information if I find out why the other App isn't working, but as of now the new one is working fine.

OTHER TIPS

I see you are catching and storing the Error Message. Did your novel happen to say what that error message was?

I also notice that your ErrorMessage string value is only 1 item, so it could be getting overwritten. You may try List(Of String) and add error messages... at least until you have had a chance to catch some of those errors.

Before going too far into this, can your device browse to the web service? If your device can not browse there, then the code in your app will not be able to get to it either.

I aggree with jp2code, before trying to adopt the code you should ensure that the device can connect to the web service.

So what is the diff between running in debugger/emulator and stand-alone on the device: the device is connected to your PC's network.

Can your device connect to the server or the web service? If not, how should your code ever success?

Check the devices network settings. Is it connected to work (windows sharing) or internet (web browsing, web services)? Do you use WLAN or GSM? What address is your web service? Is your network blocking access off WLAN or public internet (GSM)?

As said, first ensure the connection is OK before changing your working code.

BWT: If device is WLAN connected to same network as development PC you may use remote debugging via TCP/IP: VS2008 remotely connect to Win Mobile 6.1 Device Using this you have the same environment when you disconnect the ActiveSync/WMDC connection to the device.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top