Bug 57031 - C# style events not unbinding immediately from ViewTreeObserver.GlobalLayout events
Summary: C# style events not unbinding immediately from ViewTreeObserver.GlobalLayout ...
Status: CONFIRMED
Alias: None
Product: Android
Classification: Xamarin
Component: General (show other bugs)
Version: unspecified
Hardware: Macintosh Mac OS
: --- normal
Target Milestone: ---
Assignee: Jonathan Pryor
URL:
Depends on:
Blocks:
 
Reported: 2017-06-01 02:51 UTC by Kevin Ford
Modified: 2017-06-26 20:03 UTC (History)
2 users (show)

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


Attachments

Description Kevin Ford 2017-06-01 02:51:42 UTC
When subscribing to an event to the ViewTreeObserver.GlobalLayout on a view and then in the event handler unsubscribing from that event, the C# style event handlers receive the event three times even though the event is immediately unsubscribed in the event handler.

EventHandler onGlobalLayout = null;
onGlobalLayout = (sender, args) =>
{
    view.ViewTreeObserver.GlobalLayout -= onGlobalLayout;
    System.Diagnostics.Debug.WriteLine("Global Layout Happened");
};

view.ViewTreeObserver.GlobalLayout += onGlobalLayout;

When using the native style events and handlers, the event is only received once as the event is unhooked successfully and immediately the first time the event handler is called.

_View.ViewTreeObserver.AddOnGlobalLayoutListener(this);

public void OnGlobalLayout()
{
    if (_View != null)
    {
        if (Build.VERSION.SdkInt < BuildVersionCodes.JellyBean)
        {
#pragma warning disable CS0618 // Type or member is obsolete
            _View.ViewTreeObserver.RemoveGlobalOnLayoutListener(this);
#pragma warning restore CS0618 // Type or member is obsolete
        }
        else
        {
            _View.ViewTreeObserver.RemoveOnGlobalLayoutListener(this);
        }
        System.Diagnostics.Debug.WriteLine("Global Layout Happened");
    }
}

A working example of this inconsistency in how the events work can be found here:

https://github.com/Bowman74/GlobalLayoutEventTest

The application output window will show the debug message being output three times in the C# event handler activity and only once for the native event handler activity even though they should work the same.
Comment 1 Jon Douglas [MSFT] 2017-06-26 20:03:30 UTC
Marking bug as CONFIRMED as I can see the inconsistency of this between the C# styled events and java listeners with the reproduction from:

https://bugzilla.xamarin.com/show_bug.cgi?id=57031#c0

The C# events show three invocations:

[0:] Global Layout Happened
[0:] Global Layout Happened
[0:] Global Layout Happened

vs. the Java listeners showing one invocation:

[0:] Global Layout Happened

Version Information:

Microsoft Visual Studio Enterprise 2017 
Version 15.2 (26430.14) Release
VisualStudio.15.Release/15.2.0+26430.14
Microsoft .NET Framework
Version 4.7.02046

Installed Version: Enterprise

Xamarin   4.5.0.486 (fec6f88)
Visual Studio extension to enable development for Xamarin.iOS and Xamarin.Android.

Xamarin.Android SDK   7.3.1.2 (9dbc4c5)
Xamarin.Android Reference Assemblies and MSBuild support.

Xamarin.iOS and Xamarin.Mac SDK   10.10.0.37 (ad35de4)
Xamarin.iOS and Xamarin.Mac Reference Assemblies and MSBuild support.

Note You need to log in before you can comment on or make changes to this bug.