Avoid .NET Native bugs
Asked Answered
S

2

3

I spent the last year (part time) to migrate my existing (and successful) Windows 8.1 app to Windows 10 UWP. Now, just before releasing it to the store, I tested the app in the "Release" build mode (which triggers .NET Native). Everything seemed to work until I - by chance - noted a subtle but serious (because data-compromising) bug. It took me two days to reduce it to these three lines of code:

var array1 = new int[1, 1];
var array2 = (int[,])array1.Clone();
array2[0, 0] = 666;

if (array1[0, 0] != array2[0, 0]) {
    ApplicationView.GetForCurrentView().Title = "OK.";
} else {
    ApplicationView.GetForCurrentView().Title = "Bug.";
}

In Debug mode, cloning the 2D array means modifying one array item does not affect the other array. In Release mode, modifying one array changes the other, too. (I am using the latest VS 2017.)

Now, I realized that using .NET Native 1.6 (which is not the default in VS 2017), solves this particular issue.

But I lost the faith in .NET Native. How many bugs are still introduced by .NET Native into my app? My Windows 8.1 app runs fast and smoothly without .NET Native. So why should I have to use .NET Native which seems to be full of bugs? (I got to know a lot of .NET Native bugs in the last two days.)

Recently, project "UWP Desktop Bridge" has allowed to publish traditional desktop apps to the App Store (they do not have to use .NET Native). So why do I have to use .NET Native?

Is there a way to skip .NET Native totally? If not, can I configure the .NET Native compiler to behave not so destructive?

Seventeen answered 30/6, 2017 at 16:16 Comment(7)
Not an answer to your question but I must say, such things are to be expected. UWP is a great platform but its still not mature. First thing I'd do once I've verified the bug is to submit it to MS so that they eventually get around to fixing it.Antipus
Avoid Clone(). Always. It's never been adequately defined. Use Array.Copy() here instead.Comorin
(untested) In the build tab of the UWP project, you can uncheck the "compile with .NET Native tool chain" when you choose release mode. Does this not work when creating packages?Holm
Microsoft chose UWP to be the playground in order to test out .NET Native and make it mature bit by bit. You cannot fully get rid of .NET Native tool chain if you want to go through the store to publish apps. Report bugs to Microsoft and they will fix them.Weeny
@Joel Coehoorn: I have been using Clone() for over 10 years without any problems. What do you mean by "never been adequately defined"?Seventeen
@Mark W: You can create packages but you cannot publish them...Seventeen
@stybl, Lex Li: Yeah seems so. What I am afraid of is that I cannot know if I have found all bugs that .NET Native caused to my app. The bug here did not crash my app. It just led - sometimes - to strange behavior of the app. So, how many weeks should I test before publishing?Seventeen
G
7

That might be a bug on the .NET Native tool chain...

From my tests, Array.Copy works as expected:

var array1 = new int[1, 1];
var array2 = new int[1, 1];
Array.Copy(array1, array2, array1.Length);
array2[0, 0] = 666;

if (array1[0, 0] != array2[0, 0])
{
    ApplicationView.GetForCurrentView().Title = "OK.";
}
else
{
    ApplicationView.GetForCurrentView().Title = "Bug.";
}
Gannet answered 30/6, 2017 at 19:9 Comment(0)
Z
9

.NET Native dev here - sorry for the trouble you've encountered. As you said, the problem you hit with Array.Clone has been fixed (inadvertently - as a side effect of a different fix) with .NET Native 1.6 and we will be happy to fix any other issues you've encountered.

In order to bring .NET Native, we had to pretty much rewrite all of the CLR (with 15+ years of bug fixes in it). We are in the v1 stage and you're simply more likely to hit a bug in .NET Native than you are in the CLR. Most people don't encounter any bugs on either platform though. As a result of using .NET Native, Windows users can enjoy 30-60% improvements in startup time in all UWP apps (compared to CLR). It might not matter a lot on your development machine, but it matters a lot for the user experience on cheap tablets. We don't currently offer turning .NET Native off as an option.

I filed an issue to improve our test coverage for Array.Clone so that this doesn't happen again (especially because we didn't even know it was broken).

If you hit an issue in the future:

  • You can contact the dev team directly at dotnetnative (at microsoft com)
  • You can submit a fix. .NET Native for UWP apps overlaps greatly with CoreRT repo on GitHub and a lot of the code is shared.
Zacharia answered 30/6, 2017 at 22:22 Comment(4)
Thank you for your honest answer and for your filing an issue! I am sure, all of you do a great job. But as you said: It is not possible to have a mature product in a short time. So why are we forced to use .NET Native? My app has been there since the early Windows 8. My app (Win 8, 8.1) even starts fast on an old and super-slow SurfaceRT. So, don't tell me I need .NET Native. I think it's certainly great as an option. But why force us? (As a side effect, not requiring .NET Native would make F# possible for UWP.)Seventeen
Three questions: (1) Am I safe to use Clone() with .NET Native 1.6 or should I use Array.Copy() as suggested by Pedro Lamas? (2) Will I be notified when Microsoft decides to re-compile my published app (because re-compiling it in the cloud could cause new bugs)? (3) Is it possible to directly contact the managers who decided to require .NET Native?Seventeen
A fourth question: Is it safe to use attributes [StructLayout(LayoutKind.Explicit)] and [FieldOffset()]?Seventeen
1. Clone() is safe to use on .NET Native 1.6+ 2. Your app is hardcoded to the version of .NET Native you set when creating your package. We would only recompile if there's a security fix to the compiler or framework and even in that case, we would only recompile with the version you specified (plus the fix) 3. It's not possible to contact them directly. 4. Yes, explicit struct layout will work.Jahdal
G
7

That might be a bug on the .NET Native tool chain...

From my tests, Array.Copy works as expected:

var array1 = new int[1, 1];
var array2 = new int[1, 1];
Array.Copy(array1, array2, array1.Length);
array2[0, 0] = 666;

if (array1[0, 0] != array2[0, 0])
{
    ApplicationView.GetForCurrentView().Title = "OK.";
}
else
{
    ApplicationView.GetForCurrentView().Title = "Bug.";
}
Gannet answered 30/6, 2017 at 19:9 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.