zeb*_*zeb 13 c# release-builds xamarin.forms
试图在C#应用程序上调试问题,我偶然发现了这个问题,这是导致应用程序出现故障的原因.
基本上我有这个代码:
double scale = 1;
double startScale = 1;
...
scale = (e.Scale - 1) * startScale;
if(scale <= 1)
scale = 1;
...
Run Code Online (Sandbox Code Playgroud)
发生的事情是,即使scale大于1,例外进入内部如果scale最终为1.
这仅在发布版本中发生.
有没有人知道发生了什么?
编辑
这几乎(只缺少什么都没做的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;
}
}
}
Run Code Online (Sandbox Code Playgroud)
这些是我的调试会话的步骤(e.Scale已经过优化且不可见,但您可以看到CurrentScale更改的值):
CurrentScale和StartScale是实例字段而不是方法字段,因此它们可能会受到另一个线程的影响。要检测任何竞争条件,您可以在该块周围加锁并再次调试吗:
lock (StartScale) {
// Calculate the scale factor to be applied.
CurrentScale += (e.Scale - 1) * StartScale;
if(CurrentScale <= 1)
{
CurrentScale = 1;
}
}
Run Code Online (Sandbox Code Playgroud)
如果这有效,您应该使用局部变量获得更好的结果,以减少外部干扰(从而删除锁):
lock (StartScale) {
// Calculate the scale factor to be applied.
var localCurrentScale = CurrentScale + (e.Scale - 1) * StartScale;
if(localCurrentScale <= 1)
{
CurrentScale = 1;
} else CurrentScale = localCurrentScale;
}
Run Code Online (Sandbox Code Playgroud)
您可以使用 Redgate Reflector 或 Telerik JustDecompile(免费)等工具来分析编译后的程序集(它非常易读)并查看编译过程中优化了哪些内容。
注意:StartScale 是一个坏锁,但对于此调试来说没问题。
| 归档时间: |
|
| 查看次数: |
736 次 |
| 最近记录: |