Device.StartTimer & User Input

ChrisLarkinChrisLarkin USUniversity ✭✭

I'm trying to use DisplayAlert inside a callback method passed into Device.StartTimer to get a boolean response from the user on whether or not they would like to extend their current app session.

I have been unable to successfully await for their response however, because Device.StartTimer does not support async. I've tried using continueWith as well but I can't seem to get anything working.

Is it possible to await user input in the callback method that gets passed into the Device.StartTimer?

Best Answer

Answers

  • JohnHardmanJohnHardman GBUniversity mod

    @ChrisLarkin - awaiting user input in the callback from Device.StartTimer feels a slightly unnatural thing to do, but that does not mean it's impossible. To resolve the unnatural feel, you may want to fire up a new Task. Just make sure you use Device.BeginInvokeOnMainThread when interacting with the UI hierarchy.

    Also, take a look at https://forums.xamarin.com/discussion/30936/device-starttimer-async

  • ChrisLarkinChrisLarkin USUniversity ✭✭

    Thanks John - I have seen that forum post, but the chosen solution doesn't seem to answer the OP's question, it answers another posters question. I've tried implementing the solution suggested there, regardless, but it just returns immediately from DisplayAlert rather than actually awaiting.
    Would you happen to have any suggestion on how to implement auto logout functionality without relying on a timer and an alert?. The problem I'm facing is that I would like to be able to warn the user of an impending logout and give them the option to stay logged in by responding to an alert, but I can't figure out how to await their response to the alert because its kicked off from within the timer. I have tried using BeginInvokeOnMainThread() as well, but no dice.

    Here is most of the related code:

    `Device.StartTimer(TimeSpan.FromSeconds(5), () => {

    currentTime = DateTime.Now;
    var secondsRemaining = sessionLength - currentTime.Subtract(lastTokenUpdate).Seconds;
    Debug.WriteLine("There are " + secondsRemaining + " seconds remaining until next token refresh is required!");
    
    if (secondsRemaining <= 0)
        return false;
    
    if (secondsRemaining <= 60) {
        Task.Factory.StartNew(async () => {
    
        await currentPage.DisplayAlert("Session Expiring Soon", 
            "Would you like to continue using ESPMobile?","Yes", "No").ContinueWith(async (refreshResponse) => {
    
    if (refreshResponse.Result) {
    
        try {
    
            await MakeServerRequest(params).continueWith((sessionResponse) => {
                ParseServerResponse(sessionResponse.Result);
            });
        } catch(Exception e) {
    
        }
    
    }
    

    }

  • JohnHardmanJohnHardman GBUniversity mod

    @ChrisLarkin - In that code, the call to DisplayAlert needs to be wrapped by BeginInvokeOnMainThread.

    I'm just finishing for the day, but will try to take a look tomorrow if it is still not working then.

  • HunumanHunuman GBMember ✭✭✭✭
    edited August 2016

    @ChrisLarkin

    ACR Dialogs have a TimePrompt that may be of use.
    Not sure because I cant find any documentation....it may just be a way to capture time inputs....

    Anyway Hope this helps,

    Tim

  • ChrisLarkinChrisLarkin USUniversity ✭✭

    Weird, I'm positive that I had tried wrapping with that before, but I just tried it again and it worked! Thanks a lot!

Sign In or Register to comment.