0
votes

Is there some sort of limit I should be aware of when it comes to the number of consecutive and/or simultaneous animations, custom or otherwise, in Xamarin Forms?

Here's a simple example of what I'm dealing with:

    protected void ShowAlertMessage(string message)
    {
        lblAlertMessage.Text = message;

        this.AbortAnimation("AlertShow"); // crash happens with and without this...

        new Animation {
            { 0, 0.1, new Animation(v => AlertView.Opacity = v, 0.0, 1.0) },
            { 0.1, 0.6, new Animation(v => AlertView.Opacity = v, 1.0, 1.0) },
            { 0.6, 1.0, new Animation(v => AlertView.Opacity = v, 1.0, 0) },
        }.Commit(this, "AlertShow", length: 3000);
    }

The animation itself works fine. The AlertView view fades in, sustains, then fades out. I call the function again after the animation is complete, and it works fine. I call the function again while the AlertView is in the middle of a running animation, and it's still fine - it restarts the animation. However, if I mash the button that calls ShowAlertMessage() super fast, without fail, the iPhone emulator crashes with the following stack trace (I'm including the whole thing... it looks like something might be happening when a new thread is started under the covers...):

2017-06-24 12:20:37.595 RootTuner.iOS[19386:887418] critical: Stacktrace:

2017-06-24 12:20:37.596 RootTuner.iOS[19386:887418] critical:   at <unknown> <0xffffffff>
2017-06-24 12:20:37.596 RootTuner.iOS[19386:887418] critical:   at (wrapper managed-to-native) ObjCRuntime.Messaging.void_objc_msgSend_float (intptr,intptr,single) [0x0000b] in <58a9bd8a3cbb4d0092bc0a767ff66c0f>:0
2017-06-24 12:20:37.597 RootTuner.iOS[19386:887418] critical:   at CoreAnimation.CALayer.set_Opacity (single) [0x0000b] in /Users/builder/data/lanes/4691/d2270eec/source/xamarin-macios/src/build/ios/native/CoreAnimation/CALayer.g.cs:1714
2017-06-24 12:20:37.597 RootTuner.iOS[19386:887418] critical:   at Xamarin.Forms.Platform.iOS.VisualElementTracker/<>c__DisplayClass23_0.<OnUpdateNativeControl>b__0 () [0x0015a] in C:\BuildAgent\work\ca3766cfc22354a1\Xamarin.Forms.Platform.iOS\VisualElementTracker.cs:178
2017-06-24 12:20:37.597 RootTuner.iOS[19386:887418] critical:   at Xamarin.Forms.Platform.iOS.CADisplayLinkTicker.StartThread () [0x00025] in C:\BuildAgent\work\ca3766cfc22354a1\Xamarin.Forms.Platform.iOS\CADisplayLinkTicker.cs:60
2017-06-24 12:20:37.598 RootTuner.iOS[19386:887418] critical:   at System.Threading.ThreadHelper.ThreadStart_Context (object) [0x00014] in /Library/Frameworks/Xamarin.iOS.framework/Versions/10.10.0.36/src/mono/mcs/class/referencesource/mscorlib/system/threading/thread.cs:68
2017-06-24 12:20:37.598 RootTuner.iOS[19386:887418] critical:   at System.Threading.ExecutionContext.RunInternal (System.Threading.ExecutionContext,System.Threading.ContextCallback,object,bool) [0x00071] in /Library/Frameworks/Xamarin.iOS.framework/Versions/10.10.0.36/src/mono/mcs/class/referencesource/mscorlib/system/threading/executioncontext.cs:957
2017-06-24 12:20:37.598 RootTuner.iOS[19386:887418] critical:   at System.Threading.ExecutionContext.Run (System.Threading.ExecutionContext,System.Threading.ContextCallback,object,bool) [0x00000] in /Library/Frameworks/Xamarin.iOS.framework/Versions/10.10.0.36/src/mono/mcs/class/referencesource/mscorlib/system/threading/executioncontext.cs:904
2017-06-24 12:20:37.598 RootTuner.iOS[19386:887418] critical:   at System.Threading.ExecutionContext.Run (System.Threading.ExecutionContext,System.Threading.ContextCallback,object) [0x0002b] in /Library/Frameworks/Xamarin.iOS.framework/Versions/10.10.0.36/src/mono/mcs/class/referencesource/mscorlib/system/threading/executioncontext.cs:893
2017-06-24 12:20:37.599 RootTuner.iOS[19386:887418] critical:   at System.Threading.ThreadHelper.ThreadStart () [0x00008] in /Library/Frameworks/Xamarin.iOS.framework/Versions/10.10.0.36/src/mono/mcs/class/referencesource/mscorlib/system/threading/thread.cs:105
2017-06-24 12:20:37.599 RootTuner.iOS[19386:887418] critical:   at (wrapper runtime-invoke) object.runtime_invoke_void__this__ (object,intptr,intptr,intptr) [0x0004f] in <2f4074c3120b4d80802e10af84b67d41>:0
2017-06-24 12:20:37.599 RootTuner.iOS[19386:887418] critical: 
Native stacktrace:

2017-06-24 12:20:37.606 RootTuner.iOS[19386:887418] critical:   0   RootTuner.iOS                       0x000000010fdfc501 mono_handle_native_crash + 257
2017-06-24 12:20:37.607 RootTuner.iOS[19386:887418] critical:   1   RootTuner.iOS                       0x000000010fe095d0 mono_sigsegv_signal_handler + 288
2017-06-24 12:20:37.607 RootTuner.iOS[19386:887418] critical:   2   libsystem_platform.dylib            0x000000011bbfbbba _sigtramp + 26
2017-06-24 12:20:37.607 RootTuner.iOS[19386:887418] critical:   3   ???                                 0x0000000000000000 0x0 + 0
2017-06-24 12:20:37.607 RootTuner.iOS[19386:887418] critical:   4   QuartzCore                          0x000000011dc0a9ab _ZL18CAAnimation_setterP11CAAnimationj12_CAValueTypePKv + 169
2017-06-24 12:20:37.608 RootTuner.iOS[19386:887418] critical:   5   QuartzCore                          0x000000011dc03d5a -[CAAnimation setDelegate:] + 30
2017-06-24 12:20:37.608 RootTuner.iOS[19386:887418] critical:   6   UIKit                               0x0000000114057c39 -[UIViewAnimationState setAnimationAttributes:correctZeroDuration:skipDelegateAssignment:customCurve:] + 1094
2017-06-24 12:20:37.609 RootTuner.iOS[19386:887418] critical:   7   UIKit                               0x0000000114054475 -[UIViewAnimationState animationForLayer:forKey:forView:] + 1195
2017-06-24 12:20:37.609 RootTuner.iOS[19386:887418] critical:   8   UIKit                               0x0000000114055178 -[UIViewAnimationState actionForLayer:forKey:forView:] + 99
2017-06-24 12:20:37.609 RootTuner.iOS[19386:887418] critical:   9   UIKit                               0x000000011408052e +[UIView(Animation) _defaultUIViewActionForLayer:forKey:] + 111
2017-06-24 12:20:37.609 RootTuner.iOS[19386:887418] critical:   10  UIKit                               0x000000011485e8ec -[UIView(UIKitManual) actionForLayer:forKey:] + 119
2017-06-24 12:20:37.610 RootTuner.iOS[19386:887418] critical:   11  QuartzCore                          0x000000011dbda4bc -[CALayer actionForKey:] + 437
2017-06-24 12:20:37.610 RootTuner.iOS[19386:887418] critical:   12  QuartzCore                          0x000000011dbd5ade _ZL12actionForKeyP7CALayerPN2CA11TransactionEP8NSString + 76
2017-06-24 12:20:37.610 RootTuner.iOS[19386:887418] critical:   13  QuartzCore                          0x000000011dbd5a6c _ZN2CA5Layer12begin_changeEPNS_11TransactionEjRP11objc_object + 140
2017-06-24 12:20:37.611 RootTuner.iOS[19386:887418] critical:   14  QuartzCore                          0x000000011dbd5e04 _ZN2CA5Layer6setterEj12_CAValueTypePKv + 164
2017-06-24 12:20:37.611 RootTuner.iOS[19386:887418] critical:   15  QuartzCore                          0x000000011dbe1351 -[CALayer setOpacity:] + 43
2017-06-24 12:20:37.611 RootTuner.iOS[19386:887418] critical:   16  RootTuner.iOS                       0x000000010ffbe429 xamarin_dyn_objc_msgSend + 217
2017-06-24 12:20:37.611 RootTuner.iOS[19386:887418] critical:   17  ???                                 0x00000001351767f4 0x0 + 5185693684
2017-06-24 12:20:37.611 RootTuner.iOS[19386:887418] critical:   18  ???                                 0x00000001357292f4 0x0 + 5191668468
2017-06-24 12:20:37.611 RootTuner.iOS[19386:887418] critical:   19  ???                                 0x000000013572747c 0x0 + 5191660668
2017-06-24 12:20:37.612 RootTuner.iOS[19386:887418] critical:   20  RootTuner.iOS                       0x000000010fe0c585 mono_jit_runtime_invoke + 1301
2017-06-24 12:20:37.612 RootTuner.iOS[19386:887418] critical:   21  RootTuner.iOS                       0x000000010fec6b88 do_runtime_invoke + 88
2017-06-24 12:20:37.612 RootTuner.iOS[19386:887418] critical:   22  RootTuner.iOS                       0x000000010ff0d41a start_wrapper + 538
2017-06-24 12:20:37.612 RootTuner.iOS[19386:887418] critical:   23  RootTuner.iOS                       0x000000010ff91fed inner_start_thread + 189
2017-06-24 12:20:37.612 RootTuner.iOS[19386:887418] critical:   24  libsystem_pthread.dylib             0x000000011bc0daab _pthread_body + 180
2017-06-24 12:20:37.612 RootTuner.iOS[19386:887418] critical:   25  libsystem_pthread.dylib             0x000000011bc0d9f7 _pthread_body + 0
2017-06-24 12:20:37.612 RootTuner.iOS[19386:887418] critical:   26  libsystem_pthread.dylib             0x000000011bc0d1fd thread_start + 13
2017-06-24 12:20:37.613 RootTuner.iOS[19386:887418] critical: 
=================================================================
Got a SIGSEGV while executing native code. This usually indicates
a fatal error in the mono runtime or one of the native libraries 
used by your application.
=================================================================

What am I doing wrong? It does the same thing in other situations using the simple .FadeTo() and .ScaleTo() methods. The animations work, but too many causes the system to crash.

I'm using Visual Studio for Mac (Community) 7.0.1 compiling for iOS. Let me know if more specs are needed. I'm just hoping there's an animation "best practice" I'm missing!

1

1 Answers

0
votes

I managed this with two safeguards.

The first one is to lock my animation and, depending on your requirements, dismiss all animation when one is running. For example :

private bool isAnimating = false;


        private bool isAnimating = false;
        private object myObject = new object();
        private void RunAnimation()
        {
            if (isAnimating) return;
            lock (myObject)
            {
                isAnimating = true;
                try
                {
                    //my animation
                }
                finally
                {
                    isAnimating = false;
                }
            }

        }

The second safeguard when I use animation is to catch all exception and provide a fallback state (item is visible or hidden for example)

private bool isAnimating = false;
private object myObject = new object();
private void RunAnimation()
{
    if (isAnimating) return;
    lock (myObject)
    {
        isAnimating = true;
        try
        {
            //my animation
        }
        catch (Exception)
        {
            //set opacity = 1, visible = true....
        }
        finally
        {
            isAnimating = false;
        }
    }
}

There you go