locked
Ui doesn't update until end of sub or function

    Question

  • I have a 'Fire'(btnFire) Button in my game written in vb.net

    When you press the 'Fire'(btnFire) button the button needs to disappear and run the code. my code polls for an answer from the opponent so I run it async. However my Button Refuses to disappear until I receive an answer from the opponent. the code looks like this.

    PrivateAsyncSubbtnFire_Click(sender AsObject, e AsRoutedEventArgs) HandlesbtnFire.Click

            btnFire.Visibility = Windows.UI.Xaml.Visibility.Collapsed

            Await funWaitingForopponent()

    End Sub

    How do I get the btnFire.visibility to change on the main xaml form before the funWaitingForopponent() call fires instead of it waiting until End Sub to change.

    All my searches just say use the async/await feature that I'm using. but it's not working.


    • Edited by PBPuddin Thursday, May 1, 2014 8:59 PM
    Thursday, May 1, 2014 8:58 PM

Answers

  • If I had to guess I suspect that something in funWaitingForopponent is hanging the UI thread. If you have any lengthy synchronous calls you need to make sure they don't run on the UI thread. That said, what you describe should all be doable asynchronously.

        Private Function funWaitingForopponent() As Task
            Return Task.Run(AddressOf BusyLoop)
        End Function

    I can't help you beyond that if you don't provide more details. Please narrow down the problem by creating a minimal repro with just enough code to demonstrate the issue. Often this exercise will be sufficient to help you find the problem, but if not then we will have enough information about what you are doing to examine the problem.

    The following code based on what you describe causes btnFire to disappear immediately and then return when funWaitingForopponent is done.

        Private Async Sub btnFire(sender As Object, e As RoutedEventArgs)
    
            btnFire.Visibility = Windows.UI.Xaml.Visibility.Collapsed
    
            Await funWaitingForopponent()
            btnFire.Visibility = Windows.UI.Xaml.Visibility.Visible
    
    
        End Sub
    
        Private Function funWaitingForopponent() As Task
            Return Task.Delay(3000)
        End Function

    • Marked as answer by PBPuddin Saturday, May 3, 2014 6:33 PM
    Saturday, May 3, 2014 3:22 AM
    Owner

All replies

  • Hi,

    You can create a async method to make the Button Collapsed:

    Private Async Sub ButtonVisible()
    	Await btnFire.Visibility = Windows.UI.Xaml.Visibility.Collapsed
    End Sub

    And then edit your code like below:

    Private Async Sub btnFire_Click(sender AsObject, e AsRoutedEventArgs) HandlesbtnFire.Click
    
            Await ButtonVisible()
            Await funWaitingForopponent()
    
    End Sub
    
    Best Wishes!


    We are trying to better understand customer views on social support experience, so your participation in this interview project would be greatly appreciated if you have time. Thanks for helping make community forums a great place.
    Click HERE to participate the survey. Thanks<br/> MSDN Community Support<br/> <br/> Please remember to &quot;Mark as Answer&quot; the responses that resolved your issue. It is a common way to recognize those who have helped you, and makes it easier for other visitors to find the resolution later.

    Friday, May 2, 2014 2:57 AM
  • That would be nice if it was allowed. but visual studio says "Expression is of type '
    Windows.UI.Xaml.Visibility' which is not awaitable.
    Friday, May 2, 2014 4:04 AM
  • Hi,

    I am sorry for my fault! You can try to marshal the call to the UI thread with Dispatcher.RunAsync:

    Await Dispatcher.RunAsync(CoreDispatcherPriority.Normal, Function() button.Visibility = Windows.UI.Xaml.Visibility.Collapsed End Function)

    Await funWaitingForopponent()

    Best Wishes!

    We are trying to better understand customer views on social support experience, so your participation in this interview project would be greatly appreciated if you have time. Thanks for helping make community forums a great place.
    Click HERE to participate the survey. Thanks<br/> MSDN Community Support<br/> <br/> Please remember to &quot;Mark as Answer&quot; the responses that resolved your issue. It is a common way to recognize those who have helped you, and makes it easier for other visitors to find the resolution later.

    Friday, May 2, 2014 8:16 AM
  • Still no luck:( I get no error message but the button does not hide.

    to double check the functionality of the button i commented out the 'Await funWaitingForopponent(). and the button works fine. but once that await function is active it doesn't work.

    there is nothing in the awaited function that changes visibility or does anything with that button.

    Friday, May 2, 2014 3:33 PM
  • Can you provide more context? What does thefunWaitingForopponent function do? Can you post a minimal sample to your OneDrive?
    Friday, May 2, 2014 7:37 PM
    Owner
  • ok, It's Way too much code to post it all.

    the easiest way is to describe it. the problem is

    btnFire_Click runs

    btnFire.Visibility = Xaml.Visibility.Collapsed

    then runs  

    Await funWaitingForopponent() - which calls other methods to collect your move info.

                                                          then send the info to a mysql server.

                                                          then loops to check the server waiting for player ID to change to the other player( meaning that they took their turn)

    then reads there move info and sends it back to the gameboard

    then the sub btnFire_click ends - this is where the button actually disappears. of course by then the other player took their turn and the btnFire. visibility is set to show again.

    I need the visibility of the button to occur when its called, not at the end of the subroutine

    • Edited by PBPuddin Friday, May 2, 2014 8:48 PM Wrong info copied
    Friday, May 2, 2014 8:36 PM
  • If I had to guess I suspect that something in funWaitingForopponent is hanging the UI thread. If you have any lengthy synchronous calls you need to make sure they don't run on the UI thread. That said, what you describe should all be doable asynchronously.

        Private Function funWaitingForopponent() As Task
            Return Task.Run(AddressOf BusyLoop)
        End Function

    I can't help you beyond that if you don't provide more details. Please narrow down the problem by creating a minimal repro with just enough code to demonstrate the issue. Often this exercise will be sufficient to help you find the problem, but if not then we will have enough information about what you are doing to examine the problem.

    The following code based on what you describe causes btnFire to disappear immediately and then return when funWaitingForopponent is done.

        Private Async Sub btnFire(sender As Object, e As RoutedEventArgs)
    
            btnFire.Visibility = Windows.UI.Xaml.Visibility.Collapsed
    
            Await funWaitingForopponent()
            btnFire.Visibility = Windows.UI.Xaml.Visibility.Visible
    
    
        End Sub
    
        Private Function funWaitingForopponent() As Task
            Return Task.Delay(3000)
        End Function

    • Marked as answer by PBPuddin Saturday, May 3, 2014 6:33 PM
    Saturday, May 3, 2014 3:22 AM
    Owner
  • You are completely right Rob, In my loop to the sql database that checks for the opponent I found a line changing the status field on the MainPage.xaml to "Waiting For opponent" after every failed loop. when I commented this out the button disappeared. However since this was Written into the code pretty early on much of the other code was written without the async in mind. so now when I click fire the game asyncs the call to the server but then performs things that need to wait until the async method is done. ex.

    instead of clicking fire and waiting for the opponent to take there turn then updating the gameboard and changing the status to 'Your Turn'

    now it doesn't wait for a response from the other player. you click fir and the board is updated with whatever is in those variables at the time and shows status of 'Your Turn' then when the program gets a response from the other player that info is loaded into the variables but never brings them to the gameboard.

    I'm sure this is cause because I originally wrote this program without any async methods. so now I have quite a bit of restructuring to do. hehe

    thank you very much for helping my find that needle in a hay stack. you're awesome. 

    Now I'm off to start over

    Saturday, May 3, 2014 6:33 PM