[英]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. CurrentScale
和StartScale
是实例字段而不是方法字段,因此它们可能受另一个线程的影响。 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.