Unable to run Csla 3.8.x with Silverlight 4 (sl4) in Release Mode

Unable to run Csla 3.8.x with Silverlight 4 (sl4) in Release Mode

Old forum URL: forums.lhotka.net/forums/t/8914.aspx


RobKraft posted on Tuesday, May 11, 2010

We upgraded our apps to VS2010 (Visual Studio 2010) and ran OK.  We are running on Csla 3.8.

When we upgraded from Silverlight 3 (SL3 SV3) to Silverlight 4 (SL4 SV4), we also worked OK in debug mode; but when we run from release mode our code fails with these messages:

can not register property <property name> after containing type <our type> has been instantiated at....

We upgraded to Csla 3.8.3 but that has not resolved the problem.  I can't determine why this only happens when we choose a release compile.  Some of our business object calls work through Silverlight mobile Csla objects to/from the server, but then some begin to fail.

Any suggestions?  Thanks in advance.

 

RockfordLhotka replied on Tuesday, May 11, 2010

Make your property info fields public instead of private (the RegisterProperty() result).

I think SL4 may have changed their JIT compiler to include some more aggressive optimizations and/or they changed the way static fields are initialized. I haven't been able to trace down the specific thing that changed - but they did something interesting.

However, CSLA will automatically address the issue if your property info fields are public - at least that's been my observation thus far.

RobKraft replied on Wednesday, May 12, 2010

Setting those properties to public resolved the problem.  We did not have to do this for all of our classes; some work fine with private static backing fields.  Odd that this problem only occurs in the release compile of our code and only on Silverlight 4, not Silverlight 3.  I am going to try to discover another resolution though because I'd rather not clutter our object interfaces with those additional properties.

RockfordLhotka replied on Wednesday, May 12, 2010

There are only two real options - make the properties public or force static field initialization with the _forceInit trick.

I think the SL4 JIT compiler, in release mode, is now more aggressive and it is removing the _forceInit code because it doesn't actually do anything real. So if you want to use the _forceInit trick you'll have to make that code enough more complex such that the compiler thinks it is actually doing something meaningful, and thus doesn't optimize the code by removing it.

For my part, I've switched all the snippets to make the properties public, and Jonny changed the implementation so it should be safe to make them public. So my recommendation is that they be public, since that makes the problem go away without any _forceInit tricks and without worrying about compiler optimizations, etc.

RobKraft replied on Wednesday, May 26, 2010

I had to back off the upgrade to SL4 for a few weeks but I am back at it.  I was making the PropertyInfo items public, but I have discovered that creating a static constructor in each class also seems to work.

Do you see any problems with adding a static constructor in place of the _forceInit trick?

RockfordLhotka replied on Wednesday, May 26, 2010

I suspect what is happening is that the compiler (in release mode) is smart enough to realize that _forceInit is never actually used, so it optimizes that code away completely.

The supported solution is to make the PropertyInfo<T> fields public, and that's what I recommend.

If having a static constructor solves your problem, that's good too. That forces the compiler to inject some extra locking code around all static members, which is a perf impact you may or may not observe, but you should be aware that this occurs so if you do encounter perf issues you can look into whether this is a cause.

ajj3085 replied on Wednesday, June 02, 2010

RockfordLhotka
That forces the compiler to inject some extra locking code around all static members, which is a perf impact you may or may not observe, but you should be aware that this occurs so if you do encounter perf issues you can look into whether this is a cause.

I'm confused by this; I thought I checked things out under the hood a bit, and having static field initializes results in a static constructor being created for you anyway.  So I would think either  method would result in the same perf issues. 

IE:

prive static string MyString = "blah";

gets compiled to:

static MyClass() { MyString = "blah"; }

Likewise, I believe:

private string myString = "blah2";

Compiles to :

public MyClass() {  myString = "blah2"; }

(and that line is inserted at the beginning of ALL constructors)

Am I missing something?

Andy

RockfordLhotka replied on Wednesday, June 02, 2010

You could be right. My information is from a Brad Abrams blog post from a few years ago, where he walked through the whole process in some detail - for .NET (this pre-dates SL).

In his blog post he said the compiler inserts some locking code to ensure multiple threads can't run the static ctor - so it runs exactly once even in a multi-threaded setting. Of course that locking code always runs then, on every access to a static member of the type.

Maybe that's no longer accurate. Maybe it isn't accurate on SL. Then again, you'd never see it unless you run ildasm to look at the CIL that's actually being created.

Copyright (c) Marimer LLC