locked
TaskCancellationException: What am I doing wrong?

    Question

  • I am relatively new to Tasks, so the answer to this may be simple or maybe I am doing something completely wrong. What I am trying to do is display a Storyboard with several Animations (such as DoubleAnimation) and then wait for it to finish. Here is my current code:
    Private Async Function PlayCardAnimation(playerindex As Integer, row As Integer, column As Integer) As Task
    	Me.cancel = New CancellationTokenSource()
    	Me.slideboard = New Storyboard()
    	AddHandler Me.slideboard.Completed, AddressOf Me.slideboard_Completed
    	'This is where I add stuff to Me.slideboard
    	Me.slideboard.Begin()
    	Await Me.WaitForAnimation()
    	Me.cancel = Nothing
    	Me.slideboard = Nothing
    End Function
    
    Private Function WaitForAnimation() As Task
    	Return Task.Delay(-1, Me.cancel.Token)
    End Function
    
    Private Sub slideboard_Completed(sender As Object, e As Object)
    	Me.cancel.Cancel()
    End Sub
    What is currently happening is the Storyboard (Me.slideboard) runs, but then after it finishes (or at least I think it finishes, since the Completed event gets raised), I receive a TaskCancellationException on the line:
    Await Me.WaitForAnimation()
    What I was expecting to happen was the Task.Delay in Me.WaitForAnimation() would run until I cancelled it, which is what I attempt to do in slideboard_Completed, which handles the Completed event for Me.slideboard. I have confirmed that the Completed event is happening, so I am guessing the problem is in Me.cancel.Cancel() or has something to do with the overall technique I am trying to use (which may very well be, since I am inexperienced with using Tasks). Can anybody help me figure out what I am doing wrong, and what I need to do to fix it? Thanks.

    Nathan Sokalski njsokalski@hotmail.com http://www.nathansokalski.com/

    Thursday, May 7, 2015 4:40 PM

Answers

  • Hello,

    The pattern that you are using doesn't really fit the recommended asynchronous programming paradigm that we recommend. You should let your PlayCardAnimation function exit without awaiting the infinite delay. There really is no reason to do this. You know when the animation has completed via the Completed event. When you receive this event you can do what you need to finish up the transition. In other words remove the WaitForAnimation and finish up in the Completed callback.

    I hope this helps,

    James


    Windows SDK Technologies - Microsoft Developer Services - http://blogs.msdn.com/mediasdkstuff/

    Thursday, May 7, 2015 10:52 PM
    Moderator
  • Like James says, there's no good reason to delay and cancel here. I only recommended it in your other thread because you were specifically looking for a hack so you didn't need to split up a complicated function to handle the button click. The PlayCardAnimation function is simple enough to just handle the cleanup in the Completed event. You could even include it in-line as a lambda.

    For your literal question, the TaskCancellationException means exactly what it says: the task was cancelled. You can catch and ignore it in your case where you don't care about the difference between cancelled and ended. See Task Cancellation for more information.

    Thursday, May 7, 2015 11:09 PM
    Owner

All replies

  • Hello,

    The pattern that you are using doesn't really fit the recommended asynchronous programming paradigm that we recommend. You should let your PlayCardAnimation function exit without awaiting the infinite delay. There really is no reason to do this. You know when the animation has completed via the Completed event. When you receive this event you can do what you need to finish up the transition. In other words remove the WaitForAnimation and finish up in the Completed callback.

    I hope this helps,

    James


    Windows SDK Technologies - Microsoft Developer Services - http://blogs.msdn.com/mediasdkstuff/

    Thursday, May 7, 2015 10:52 PM
    Moderator
  • Like James says, there's no good reason to delay and cancel here. I only recommended it in your other thread because you were specifically looking for a hack so you didn't need to split up a complicated function to handle the button click. The PlayCardAnimation function is simple enough to just handle the cleanup in the Completed event. You could even include it in-line as a lambda.

    For your literal question, the TaskCancellationException means exactly what it says: the task was cancelled. You can catch and ignore it in your case where you don't care about the difference between cancelled and ended. See Task Cancellation for more information.

    Thursday, May 7, 2015 11:09 PM
    Owner