简体   繁体   English

C#在发布版本中不起作用

[英]C# is not working in release build

Trying to debug a problem on a C# application, I stumbled upond this problem which is the cause of the app malfunctioning. 试图在C#应用程序上调试问题,我偶然发现了这个问题,这是导致应用程序出现故障的原因。

Basically I have this code: 基本上我有这个代码:

double scale = 1;
double startScale = 1;
...
scale = (e.Scale - 1) * startScale;
if(scale <= 1)
    scale = 1;
...

What happens is that even if scale is greater than 1 the excecution enters inside the if the scale ends up being Always 1. 会发生的是,即使scale大于1,如果scale最终为1,则执行进入内部。

This happens only in release build. 这仅在发布版本中发生。

Does anyone have an idea of what's going on? 有没有人知道发生了什么?

EDIT 编辑

This is the, almost (missing only the ctor which does nothing, of a custom control for Xamarin Forms, taken from their example to implement a pinch gesture ( here ). 这几乎(只缺少什么都没做的ctor,Xamarin Forms的自定义控件,取自他们的例子来实现捏手势( 这里 ))。

public class PinchView : ContentView
{
    private double StartScale = 1;
    private double CurrentScale = 1;
    private double XOffset = 0;
    private double YOffset = 0;

    ...

    private void PinchGesture_PinchUpdated(object sender, PinchGestureUpdatedEventArgs e)
    {
        if (e.Status == GestureStatus.Started)
        {
            // Store the current scale factor applied to the wrapped user interface element,
            // and zero the components for the center point of the translate transform.
            StartScale = Content.Scale;
            Content.AnchorX = 0;
            Content.AnchorY = 0;
        }

        if (e.Status == GestureStatus.Running)
        {
            // Calculate the scale factor to be applied.
            CurrentScale += (e.Scale - 1) * StartScale;
            if(CurrentScale <= 1)
            {
                CurrentScale = 1;
            }

            // The ScaleOrigin is in relative coordinates to the wrapped user interface element,
            // so get the X pixel coordinate.
            double renderedX = Content.X + XOffset;
            double deltaX = renderedX / Width;
            double deltaWidth = Width / (Content.Width * StartScale);
            double originX = (e.ScaleOrigin.X - deltaX) * deltaWidth;

            // The ScaleOrigin is in relative coordinates to the wrapped user interface element,
            // so get the Y pixel coordinate.
            double renderedY = Content.Y + YOffset;
            double deltaY = renderedY / Height;
            double deltaHeight = Height / (Content.Height * StartScale);
            double originY = (e.ScaleOrigin.Y - deltaY) * deltaHeight;

            // Calculate the transformed element pixel coordinates.
            double targetX = XOffset - (originX * Content.Width) * (CurrentScale - StartScale);
            double targetY = YOffset - (originY * Content.Height) * (CurrentScale - StartScale);

            // Apply translation based on the change in origin.
            Content.TranslationX = targetX.Clamp(-Content.Width * (CurrentScale - 1), 0);
            Content.TranslationY = targetY.Clamp(-Content.Height * (CurrentScale - 1), 0);

            // Apply scale factor.
            Content.Scale = CurrentScale;
        }

        if (e.Status == GestureStatus.Completed)
        {
            // Store the translation delta's of the wrapped user interface element.
            XOffset = Content.TranslationX;
            YOffset = Content.TranslationY;
        }
    }
}

These are steps of my debug session ( e.Scale has been optimized and isn't visible, but you can see the value of CurrentScale changing): 这些是我的调试会话的步骤( e.Scale已经过优化且不可见,但您可以看到CurrentScale的值发生变化):

在此输入图像描述

在此输入图像描述

在此输入图像描述

在此输入图像描述

在此输入图像描述

CurrentScale and StartScale are instance fields and not method fields, so they can be affected by another thread. CurrentScaleStartScale是实例字段而不是方法字段,因此它们可能受另一个线程的影响。 To detect any race condition, can you put a lock around this bloc and debug again: 要检测任何竞争条件,您是否可以锁定此块并再次调试:

lock (StartScale) {
    // Calculate the scale factor to be applied.
    CurrentScale += (e.Scale - 1) * StartScale;
    if(CurrentScale <= 1)
    {
        CurrentScale = 1;
    }
}

If this works, you should have better results with local variables to reduce external interferences (and so remove the lock): 如果这样做,您应该使用局部变量获得更好的结果,以减少外部干扰(并因此删除锁定):

lock (StartScale) {
    // Calculate the scale factor to be applied.
    var localCurrentScale = CurrentScale + (e.Scale - 1) * StartScale;
    if(localCurrentScale <= 1)
    {
        CurrentScale = 1;
    } else CurrentScale = localCurrentScale;
}

You can use tools like Redgate Reflector or Telerik JustDecompile (free) to analyze your compiled assembly (it's pretty readable) and see what's been optimized during the compilation. 您可以使用Redgate Reflector或Telerik JustDecompile(免费)等工具来分析编译的程序集(它非常易读),并查看编译期间的优化内容。

NB: StartScale is a bad lock but is fine for this debugging. 注意:StartScale是一个糟糕的锁,但对于这个调试很好。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM