UI interaction/cancel during AsyncGetToFile wait loop

What is the proper way to handle UI events during roUrlTransfer.AsyncGetToFile(filename)?

I don’t seem to get the events on the same message port as the url message port because, well, they are different ports. When a roPosterScreen is on top, using psPort, then I call the AsyncGetToFile() on the roUrlTransfer object which uses utPort.

While waiting for the urlTransfer asyncronous call to return, if I press UP (remember the posterscreen is still showing, then my posterscreen disappears and shows the next (appropriate) screen on the stack. At the same time, my code is still waiting for the URL transfer to finish and thus becomes unsyncronized from the UI. It eventually corrects itself, but would likely cause user confusion.

What is the right way to go about allowing a UI event to cancel the AsyncGetToFile() loop?

    m.Http.EnableFreshConnection(true) 'Don't reuse existing connections
    if (m.Http.AsyncGetToFile(filename))
        event = wait(timeout%, m.Http.GetPort())
        if type(event) = "roUrlEvent"
            print "***";event.GetInt();
            print "***";event.GetResponseCode();
            print "***";event.GetFailureReason();
            print "***";event.GetSourceIdentity()
        elseif event = invalid
            print "AsyncGetToFile timeout"
            m.Http.AsyncCancel()
        else
            print "AsyncGetToFile unknown event: "; event
        endif
    endif

It seems, sadly, that I may have to unwrap the loop and place the file handling/parsing within the UI loop. Can anyone confirm this?

I’m also seeing a timing issue using a mostly unmodified urlUtils.brs:
During a call using a (wait) timeout of 45 seconds, I get a urlEvent:
*** 1***-28Connection timed out after 30005 milliseconds 1235

I don’t see any way to change the timeout of the roUrlTransfer.AsyncGetToFile() call to anything different than 30 seconds.

Are you opposed to sharing ports? There’s no reason all of your components couldn’t use the same message port, so all of your wait loops could be setup to listen for roUrlTransfer events. You can also cancel an async transfer using the AsyncCancel method of roUrlTransfer.

Something along the lines of this, maybe?

While True
    msg = Wait(0, m.GlobalMessagePort)
    If Type(msg) = "roUrlTransferEvent" Then
        HandleUrlEvent(msg)
    Else If Type(msg) = "roXXXXScreenEvent" Then
        If msg.IsScreenClosed() Then
            ' The screen is closing, so cancel any async transfers
            m.UrlTransfer.AsyncCancel()
        End If
    End If
End While

Oh, and you’re right. The maximum timeout for any roUrlTransfer request is 30 seconds. There’s not way to change that currently. You can always cancel it sooner, but you can’t extend it.

Thanks!

I’m not opposed to sharing message ports (and I do so elsewhere in the channel application), but my object model for that object is currently “retrieve file, parse file” all in one atomic synchronous call. To accommodate/combine into one message port, I’ll have to split my object handling to retrieving and parsing separately. Not impossible, just need to determine when (during development) to do the change.