Bug 58175 - Property Get called before constructor finishes
Summary: Property Get called before constructor finishes
Status: RESOLVED INVALID
Alias: None
Product: Android
Classification: Xamarin
Component: Mono runtime / AOT Compiler ()
Version: unspecified
Hardware: PC Windows
: --- normal
Target Milestone: ---
Assignee: Marek Habersack
URL:
Depends on:
Blocks:
 
Reported: 2017-07-15 00:51 UTC by Adam
Modified: 2017-08-04 13:04 UTC (History)
3 users (show)

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


Attachments
Example project that shows the issue (1.40 MB, application/x-zip-compressed)
2017-07-15 00:51 UTC, Adam
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 on Developer Community or GitHub with your current version information, steps to reproduce, and relevant error messages or log files if you are hitting an issue that looks similar to this resolved bug and you do not yet see a matching new report.

Related Links:
Status:
RESOLVED INVALID

Description Adam 2017-07-15 00:51:38 UTC
Created attachment 23577 [details]
Example project that shows the issue

[Video, with a walkthrough showing the bug in action]: https://vimeo.com/225633853/bf3b02d0f6

I have the following code in my ViewModel. 

public LoginViewModel(IAuthModel model) :
 base(new LoginVisualState(model))    
{      
	_model = model;
}
    
public IRelayCommand LoginCommand    
{      
	get      
	{        
		return GetCommand(() =>
        			{          
					return Execution.ViewModelExecute(new LoginOperation(_model));        
				});      
	}
}


Now, I thought that before any 'get' can be performed on the LoginCommand, it must complete the constructor first. This runs as expected on UWP, constructor first, then 'get'. But on Android, it runs the 'get' in the property first, then the constructor. 

Now to go even stranger, if I then go into the GetCommand method, and put a return if the Execution property is null in there, as so.

public IRelayCommand GetCommand(Func<IRelayCommand> create, [CallerMemberName] string name = "")    
{      
	// This is what i just added in      
	if (Execution == null)        
		return null;      

	// This is the existing code.      
	if (!commands.ContainsKey(name))
 		commands.Add(name, create());            

	return commands[name];
        
}

Then the constructor always runs first, then the 'get' in the property. If I comment out those first 2 lines, it reverts back to it's previous way of running the 'get' before constructor. Am I missing something, or is this a strange bug? I am thinking a compiler optimization issue.

Attached is the project where this issue occurs.


Below is my Visual Studio setup.

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

Installed Version: Enterprise

Architecture Diagrams and Analysis Tools   00369-90252-65973-AA415
Microsoft Architecture Diagrams and Analysis Tools

Visual Basic 2017   00369-90252-65973-AA415
Microsoft Visual Basic 2017

Visual C# 2017   00369-90252-65973-AA415
Microsoft Visual C# 2017

Visual C++ 2017   00369-90252-65973-AA415
Microsoft Visual C++ 2017

Visual F# 4.1   00369-90252-65973-AA415
Microsoft Visual F# 4.1

Application Insights Tools for Visual Studio Package   8.6.00404.2
Application Insights Tools for Visual Studio

ASP.NET and Web Tools 2017   15.0.30503.0
ASP.NET and Web Tools 2017

ASP.NET Web Frameworks and Tools 2017   5.2.50303.0
For additional information, visit https://www.asp.net/

Azure App Service Tools v3.0.0   15.0.30209.0
Azure App Service Tools v3.0.0

Azure Data Lake Node   1.0
This package contains the Data Lake integration nodes for Server Explorer.

Azure Data Lake Tools for Visual Studio   2.2.5000.0
Microsoft Azure Data Lake Tools for Visual Studio

Common Azure Tools   1.9
Provides common services for use by Azure Mobile Services and Microsoft Azure Tools.

Fabric.DiagnosticEvents   1.0
Fabric Diagnostic Events

GitHub.VisualStudio   2.2.0.11
A Visual Studio Extension that brings the GitHub Flow into Visual Studio.

JavaScript Language Service   2.0
JavaScript Language Service

JavaScript Project System   2.0
JavaScript Project System

JavaScript UWP Project System   2.0
JavaScript UWP Project System

KofePackagePackage Extension   1.0
KofePackagePackage Visual Studio Extension Detailed Info

Merq   1.1.17-rc (cba4571)
Command Bus, Event Stream and Async Manager for Visual Studio extensions.

Microsoft Azure Hive Query Language Service   2.2.5000.0
Language service for Hive query

Microsoft Azure Tools   2.9
Microsoft Azure Tools for Microsoft Visual Studio 2017 - v2.9.50131.1

Microsoft MI-Based Debugger   1.0
Provides support for connecting Visual Studio to MI compatible debuggers

Microsoft Visual Studio VC Package   1.0
Microsoft Visual Studio VC Package

Mono Debugging for Visual Studio   Mono.Debugging.VisualStudio
Support for debugging Mono processes with Visual Studio.

NuGet Package Manager   4.2.0
NuGet Package Manager in Visual Studio. For more information about NuGet, visit http://docs.nuget.org/.

SQL Server Data Tools   15.1.61702.140
Microsoft SQL Server Data Tools

ToolWindowHostedEditor   1.0
Hosting json editor into a tool window

TypeScript   2.2.2.0
TypeScript tools for Visual Studio

Visual C++ for Cross Platform Mobile Development (Android)   15.0.26228.00
Visual C++ for Cross Platform Mobile Development (Android)

Visual Studio Tools for Universal Windows Apps   15.0.26430.06
The Visual Studio Tools for Universal Windows apps allow you to build a single universal app experience that can reach every device running Windows 10: phone, tablet, PC, and more. It includes the Microsoft Windows 10 Software Development Kit.

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.
Comment 1 Jon Douglas [MSFT] 2017-07-21 17:42:19 UTC
Hi Adam,

Thank you for the report. I attempted to reproduce this behavior with your default project (Not modifying any workarounds), I run into the expected behavior when debugging. That is of course hitting the CTOR and then the get. 

https://www.screencast.com/t/cizSqBLIAZpm

Some other details that might be helpful:

What API are you deploying to? I tried 19, 21, 24 for some quick tests.

Is this 100% reproducible? Have you tried multiple devices/emulators and the API combinations between the two?

Seeing that I'm on the same build as you, this seems to be a little more specific to something else. Can you let me know via a few tests if we can figure out what the odd thing out is?

Thanks!
Comment 2 Adam 2017-07-22 00:52:58 UTC
Hi Jon

I just did some more testing and yes, I can continue to reproduce it, 100% of the time. The Video link I attached to the original report, showing it in action, is exactly what is happening.

I am deploying on Min API 16 and Compiling against API 25. I did also try API 24 and 23, then changing the Min to 21.

I have tried on the emulator (Android 6.0 x86) and I have tried on a real device (Sony Xperia F3115, Android 7.0).

This occurs in both Debug and Release mode.

The GetCommand will always run before the CTOR, unless I put in
if (Execution == null)        
    return null;      


I am currently building with no AOT, no Shared Runtime, no ProGuard, no linking.

Happy to try out anything more, if you have any suggestions. My local PC is an Intel i7-7700HQ Kaby Lake, if that might have anything to do with it.
Comment 3 Adam 2017-07-29 01:57:26 UTC
Forgot to change status back to NEW
Comment 4 Jon Douglas [MSFT] 2017-08-03 17:08:57 UTC
(In reply to Adam from comment #2)
> Hi Jon
> 
> I just did some more testing and yes, I can continue to reproduce it, 100%
> of the time. The Video link I attached to the original report, showing it in
> action, is exactly what is happening.
> 
> I am deploying on Min API 16 and Compiling against API 25. I did also try
> API 24 and 23, then changing the Min to 21.
> 
> I have tried on the emulator (Android 6.0 x86) and I have tried on a real
> device (Sony Xperia F3115, Android 7.0).
> 
> This occurs in both Debug and Release mode.
> 
> The GetCommand will always run before the CTOR, unless I put in
> if (Execution == null)        
>     return null;      
> 
> 
> I am currently building with no AOT, no Shared Runtime, no ProGuard, no
> linking.
> 
> Happy to try out anything more, if you have any suggestions. My local PC is
> an Intel i7-7700HQ Kaby Lake, if that might have anything to do with it.

I had attempted this on three physiacal different devices(API 23, 24, 25) using 15.2. I also tried a few x86 emulators (24-25) The behavior remains what you would "Expect" on each device which is the constructor being executed prior to the get call.

15.3 (Preview 7.0) isn't really testable as it shows:

Checking compatibility for Xamarin.Forms 2.3.4.214-pre5 with .NETStandard,Version=v1.3.
NU1202: Package Xamarin.Forms 2.3.4.214-pre5 is not compatible with netstandard1.3 (.NETStandard,Version=v1.3). Package Xamarin.Forms 2.3.4.214-pre5 supports:
  - monoandroid10 (MonoAndroid,Version=v1.0)
  - portable-monoandroid10+net45+win+win81+wp8+wpa81+xamarinios10+xamarinmac20 (.NETPortable,Version=v0.0,Profile=win+net45+wp80+win81+wpa81+MonoAndroid10+Xamarin.iOS10+xamarinmac20)
  - uap10.0 (UAP,Version=v10.0)
  - win81 (Windows,Version=v8.1)
  - wp8 (WindowsPhone,Version=v8.0)
  - wpa81 (WindowsPhoneApp,Version=v8.1)
  - xamarinios10 (Xamarin.iOS,Version=v1.0)			

Perhaps a need to upgrade to .netstandard 1.0 supported package:

https://www.nuget.org/packages/Xamarin.Forms/2.3.5.256-pre6

System Specs:

Intel(R) Core(TM) i7-6700K CPU @ 4.00GHz, 4001 Mhz, 4 Core(s), 8 Logical Processor(s)

Unfortunately I do not have a Kaby Lake. I will however ask a few colleagues to test this.
Comment 5 Marek Safar 2017-08-04 11:26:16 UTC
Could you attach a stack-trace from what you see as wrong get invocation
Comment 6 Adam 2017-08-04 13:04:24 UTC
I should have checked the call stack before. Sorry guys, my bad. Perfect storm of oversights on my part. Reflection happening in my base class constructor, picking up the properties, and that wasn't in the sample I uploaded.

Again, really sorry for the wild goose chase, I feel really bad for wasting your time.