SIGABRT 在模型 c# 中抛出 xamarin 表单自定义 getter/setter

SIGABRT thrown xamarin forms custom getter/setter in model c#

**

通知; 21-12-2018 - 更改了问题的名称以符合此问题的新实例。有关此的信息在底部。

**

我已经为这个错误苦苦挣扎了 3 周,尝试了我能想到的一切,甚至重新安装了 visual studio 2017。

首先介绍一下背景故事;

我正在开发一个可以订购三明治的应用程序,并且大部分重要功能都已完成。在过去的 4 个月里,整个订购流程一直在运作。几周前有一个灾难周,保险丝盒烧坏导致停电。这不知何故打破了防火墙,整个公司网络都崩溃了。在安装 android 工作室期间(以及视觉 studio/xamarin)。几天后 visual studio 2017 的更新出现问题,我进行了完整的重新安装并删除了 android studio。然后错误开始出现。

大多数应用程序仍然可以正常工作,但是您可以登录、查看购物车、浏览类别等;当在 REST 实现中调用特定函数时,应用程序关闭并且调试器显示 Fatal signal 6 SIGABRT -6 错误。

12-07 12:57:29.409 F/ (20795): * Assertion at /Users/builder/jenkins/workspace/xamarin-android-d15-9/xamarin-android/external/mono/mono/mini/unwind.c:640, condition `cfa_reg != -1' not met

12-07 12:57:29.409 F/libc (20795): Fatal signal 6 (SIGABRT), code -6 in tid 20828 (Thread Pool Wor), pid 20795 (e.Appnamehere)

代码如下:

public async Task<ObservableCollection<T>> GetAllWithId<T>(Guid id)
{
    var t = typeof(T);
    var uri = GetURI<T>();
    ObservableCollection<T> oc = new ObservableCollection<T>();
    try
    {
        var tmpUri = "";
        // IF statements to determine URI, if no ifs succeed let run and catch exception.. ps. can be changed for typeswitch
        if (typeof(T) == typeof(Product)) { tmpUri = uri + "/incategory/" + id; }/*use category id inside*/
        if (typeof(T) == typeof(Order)) { tmpUri = uri + "/fromuser/" + id; }/*use user id*/
        var client = GetNewClient();
        using (client)
        {
            HttpResponseMessage result = await client.GetAsync(tmpUri);
            if (result.IsSuccessStatusCode)
            {
                var content = await result.Content.ReadAsStringAsync();
                Debug.WriteLine(content);             
                oc = JsonConvert.DeserializeObject<ObservableCollection<T>>(content);// <<<<<< SIGABRT THROWN HERE
                //* Assertion at /Users/builder/jenkins/workspace/xamarin-android-d15-9/xamarin-android/external/mono/mono/mini/unwind.c:640, condition `cfa_reg != -1' not met
            }
        }
    }
    catch (Exception ex)
    {
        Debug.WriteLine(@"ERROR {0}", ex.Message);
    }

    return oc;
}

有一种实现使用了所有控制器都使用的泛型。 getURIgetNewClient 方法分别将 URI 构建为相应的类型并返回客户端实例。

自开发开始以来,xamarin 核心和其他包一直没有更新,因为这通常会破坏一些东西。所有包的当前版本与开发开始时(即没有错误时)相同。 (底部的包和版本列表)。

错误在 newtonsoft.json 包的最后两个版本上执行(错误从 v11.0.2 开始,然后我更新到 v12.0.1,错误仍然存​​在)。 API 数据从中检索并按预期工作,returns 数据格式正确。 调试器没有显示堆栈跟踪,但确实指出错误通常是由本机单代码或依赖项使用的本机代码引起的。

如果有人需要更多信息,我很乐意提供,因为我在 google 上找不到任何关于如何解决这个问题的信息。

该错误也发生在所有模拟器上(从 512mb 到 2gb ram,不同的堆大小和不同的渲染器。我无法使用物理设备进行测试,因为网络仍处于锁定状态并且设备无法连接)

更新;它是固定的(我认为)。 20-12-2018

我在 API 端显式构建对象并将它们作为相应类型(即产品、订单等)的对象而不是 var.

发送

在反序列化、重新序列化并再次重复之后,我最终得到了一个有效但效率极低的解决方案。

之后,我在模型的属性上剪切了几个自定义 getters 和 setters。 (这绝不是此问题的指定原因,但它有助于解决问题。)

它仍然有效,然后我尝试使用问题中显示的原始代码行,它有效。

注意,我做了 re-install visual studio 两次..(从 15.9.2 更新到 15.9.3 时有一次,昨天卸载了它并使用新更新 15.9.4 安装了它).

这是在旧分支上完成的,该分支仍然具有所有依赖项的原始版本。

总而言之,这个错误应该不是反序列化对象不匹配导致的错误。这样的错误应该作为反序列化错误或类似的东西抛出,而不是抛出本机单声道展开错误。

(导致此错误的代码行被两个嵌套的 try-catch 块包围..)

更新..又发生了 21-12-2018

所以错误昨天消失了。我希望它是永远的,但现在它 re-occurred。我将其缩小到产品模型。 (因为最初的错误发生在加载产品和加载历史订单时,它们只共享相同的 API 方法,所以它必须在那里,它也是)。

抛出同样的错误,除了现在历史订单仍然有效,除了产品不起作用。它发生在我向我的模型添加自定义 getter 和 setter 时。下面的代码;

public Object ProductImage {
             get { return ProductImage; }
             set {

                try
                {
                    if (value.ToString().Contains("/api/DynamicImages/getimageonly/"))
                    {
                        string imreBase64Data = Convert.ToBase64String(Constants.ObjectToByteArray(value));
                        ProductImage = string.Format("data:image/png;base64,{0}", imreBase64Data);
                    }
                    else
                    {
                        ProductImage = value;
                    }


                }
                catch (Exception ex) { ProductImage = value; }


            }
           //   get;set;//<-- when i use this instead no signal abort is thrown but the images wont load when they are retrieved as either a file or data from my own API. (images retrieved as link to external site still work, falling back to place holders still works too.)
        }

当我恢复到简单的 get;set; 时有用。有接盘者吗? 笔记;我更新了问题的名称,以便更具体地针对这个新问题。

根本原因是non-stop递归调用。
例如:
ProductImage = value -> 它会再次触发调用 setter。
结果,setter 被一次又一次地调用。

在java中,遇到这种情况会报Whosebug错误。
但是,在mono中,它显示这样的错误消息,调试不清楚。

解决方法是:

private Object _productImage;
public Object ProductImage {
    get { return _productImage; }
    set {
    ... 
    _productImage = {some value};
    }
}