Bug 41016 - An attempt was made to transition a task to a final state when it had already completed.
Summary: An attempt was made to transition a task to a final state when it had already...
Status: CONFIRMED
Alias: None
Product: Forms
Classification: Xamarin
Component: Forms ()
Version: unspecified
Hardware: PC Windows
: Normal major
Target Milestone: ---
Assignee: Bugzilla
URL:
Depends on:
Blocks:
 
Reported: 2016-05-11 11:49 UTC by guitarpark
Modified: 2018-01-22 10:22 UTC (History)
9 users (show)

Tags: ac
Is this bug a regression?: ---
Last known good build:


Attachments
Double await within Command or BeginInvokeOnMain causing break (56.78 KB, application/x-zip-compressed)
2016-07-20 21:25 UTC, Tony
Details


Notice (2018-05-24): bugzilla.xamarin.com is now in read-only mode.

Please join us on Visual Studio Developer Community and in the Xamarin and Mono organizations on GitHub to continue tracking issues. Bugzilla will remain available for reference in read-only mode. We will continue to work on open Bugzilla bugs, copy them to the new locations as needed for follow-up, and add the new items under Related Links.

Our sincere thanks to everyone who has contributed on this bug tracker over the years. Thanks also for your understanding as we make these adjustments and improvements for the future.


Please create a new report for Bug 41016 on Developer Community or GitHub if you have new information to add and do not yet see a matching new report.

If the latest results still closely match this report, you can use the original description:

  • Export the original title and description: Developer Community HTML or GitHub Markdown
  • Copy the title and description into the new report. Adjust them to be up-to-date if needed.
  • Add your new information.

In special cases on GitHub you might also want the comments: GitHub Markdown with public comments

Related Links:
Status:
CONFIRMED

Description guitarpark 2016-05-11 11:49:19 UTC
btnTapped.GestureRecognizers.Add(new TapGestureRecognizer
            {
                Command = new Command(async (o) =>
                {
                    await btnTapped.FadeTo(0.5, 50);
                    //some code
                    await btnTapped.FadeTo(1, 50);
                })
            });


if i click this very fast,then display error:
An attempt was made to transition a task to a final state when it had already completed.
Comment 1 Paul DiPietro [MSFT] 2016-05-12 16:30:54 UTC
We'd be happy to help you resolve this issue. Please help us by attaching a reduced reproduction to the bug by starting with a clean Xamarin.Forms project and adding just the code necessary to demonstrate the issue. If you'd do this for us we would very much appreciate it. If you are able to reproduce the issue without modifying the platform specific projects that would eliminate a number of possibilities and likely expedite a resolution. 

Warm regards,
Xamarin Forms Team
Comment 2 mbellini 2016-07-12 12:54:04 UTC
Same problem here, any news? The code and error are just like @guitarpark's ones.
Comment 3 Tony 2016-07-20 21:25:19 UTC
Created attachment 16733 [details]
Double await within Command or BeginInvokeOnMain causing break

I have this same issue.

This also happens from any Device.BeginInvokeOnMainThread when you have to awaited functions in the one block.

This is easily to replicate from the example give by @guitarpark if you increase the fade time to 1,000 for each fade you can press twice in about 1s to make it crash.

10,000 then you have approx 10s to press it twice and make it crash ect.

I will attach an example with the 10,000 fade delay as asked by @Paul DiPietro
Comment 4 Tony 2016-08-03 21:21:57 UTC
Any update on the issue?
Comment 5 Paul DiPietro [MSFT] 2016-08-04 16:11:37 UTC
Thanks for providing the reproduction. We'll look into this.
Comment 6 aed 2016-09-03 17:49:32 UTC
Reproes for me as well and makes it pretty hard to use animations on XF Android.

Example stack trace (though it happens for all animations)

System.Threading.Tasks.TaskCompletionSource<TResult>.SetResult(TResult result)<ac06fdfab2d74ebaa0c1e77da6f7aafd>:0
Xamarin.Forms.ViewExtensions.<>c__DisplayClass1_0.<FadeTo>b__1(double f, bool a)<bea3d2470366424b9c3e393383a0f6e3>:0
Xamarin.Forms.AnimationExtensions.<>c__DisplayClass13_0<T>.<AnimateInternal>b__1(double f, bool b)<bea3d2470366424b9c3e393383a0f6e3>:0
Xamarin.Forms.AnimationExtensions.AbortAnimation(AnimatableKey key)<bea3d2470366424b9c3e393383a0f6e3>:0
Xamarin.Forms.AnimationExtensions.AnimateInternal<T>(IAnimatable self, string name, Func<T, TResult> transform, Action<T> callback, uint rate, uint length, Easing easing, Action<T1, T2> finished, Func<TResult> repeat)<bea3d2470366424b9c3e393383a0f6e3>:0
Xamarin.Forms.AnimationExtensions.<>c__DisplayClass7_0<T>.<Animate>b__0()<bea3d2470366424b9c3e393383a0f6e3>:0
Xamarin.Forms.AnimationExtensions.Animate<T>(IAnimatable self, string name, Func<T, TResult> transform, Action<T> callback, uint rate, uint length, Easing easing, Action<T1, T2> finished, Func<TResult> repeat)<bea3d2470366424b9c3e393383a0f6e3>:0
Xamarin.Forms.AnimationExtensions.Animate(IAnimatable self, string name, Action<T> callback, uint rate, uint length, Easing easing, Action<T1, T2> finished, Func<TResult> repeat)<bea3d2470366424b9c3e393383a0f6e3>:0
Xamarin.Forms.AnimationExtensions.Animate(IAnimatable self, string name, Animation animation, uint rate, uint length, Easing easing, Action<T1, T2> finished, Func<TResult> repeat)<bea3d2470366424b9c3e393383a0f6e3>:0
Xamarin.Forms.Animation.Commit(IAnimatable owner, string name, uint rate, uint length, Easing easing, Action<T1, T2> finished, Func<TResult> repeat)<bea3d2470366424b9c3e393383a0f6e3>:0
Xamarin.Forms.ViewExtensions.FadeTo(VisualElement view, double opacity, uint length, Easing easing)<bea3d2470366424b9c3e393383a0f6e3>:0
Comment 7 adrianknight89 2016-09-24 04:25:12 UTC
Maybe I'm misunderstanding the issue here, but why is this a problem at all? Once you tap the button, the UI thread allows you to tap again. While the first await is executing, you then try to execute another await of the same kind (btnTapped.FadeTo(0.5, 50);). This messes up animations.

What is the purpose of tapping multiple times while the first tap hasn't finished?

You should disable the button when command begins executing and enable it before it finishes.
Comment 8 Tony 2016-10-03 19:29:37 UTC
adrianknight89@outlook.com
The point here is that this is an issue for all running tasks.
It's the same for anything using begin on main thread as well.

I have a case where I dismiss a popup and then show a new popup on the page and assuming the user clicks something within a couple of second it crashes because its got an await on dismiss and on show.

Also just because you should disable the button doesn't mean that you can rely on the disable happening. In the case of user double tapping quickly it is not always possible to stop the second click from happening as these happen on separate threads and disabling on the first doesn't always disable before the second thread runs the click action.

The worst possible state for an app to have is one where the app crashes unexpectedly and this bug is one of such issues.
Comment 9 aed 2016-10-03 19:41:25 UTC
While I see Adrian's point, the alternative is for every app to have a bunch of synchronization and locks just for some trivial animations.

This is actually how I got around this bug in the end but it ended up being a behemoth of code which is not ideal. If a user clicks a star I make it go bigger and smaller over 100ms. This code alone has calls to lock (because some times, two taps are received within one millisecond), and any code which tries to make the star animate has calls to lock. 

And any time I make any change to animations I have to worry about all the locks. It feels like developing a game, but for something like Xamarin Forms it's a little overkill. I'd also be fine with this as a warning but it crashes the app entirely.