【发布时间】:2023-03-26 22:17:01
【问题描述】:
**
通知; 21-12-2018 - 更改了问题的名称以符合此问题的新实例。有关这方面的信息在底部。
**
我已经为这个错误苦苦挣扎了 3 周,尝试了我能想到的一切,甚至重新安装了 Visual Studio 2017。
先说一点背景故事;
我正在开发一个可以订购三明治并且大部分重要功能都已完成的应用。在过去的 4 个月里,整个订购过程一直在运作。几周前有一个灾难周,保险丝盒烧坏导致停电。这不知何故破坏了防火墙,整个公司网络都瘫痪了。在安装 android studio 期间(与 visual studio/xamarin 一起)。几天后,Visual Studio 2017 的更新出错了,我完全重新安装并删除了 android Studio。然后错误开始出现。
大多数应用程序仍然可以正常工作,但是您可以登录、检查购物篮、浏览类别等;当在 REST 实现中调用特定函数时,应用程序关闭并且调试器显示致命信号 6 SIGABRT -6 错误。
12-07 12:57:29.409 F/ (20795): * 断言在 /Users/builder/jenkins/workspace/xamarin-android-d15-9/xamarin-android/external/mono/mono/mini/unwind .c:640,条件 `cfa_reg != -1' 不满足
12-07 12:57:29.409 F/libc (20795):致命信号 6 (SIGABRT),tid 20828(线程池工作)中的代码 -6,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;
}
有一种实现使用所有控制器都使用的泛型。 getURI 和 getNewClient 方法分别构建对应类型的 URI 并返回一个客户端实例。
自开发开始以来,xamarin 核心和其他软件包没有更新,因为这通常会破坏东西。所有软件包的当前版本与开发开始时(即没有错误时)相同。 (底部的软件包和版本列表)。
该错误在最后 2 个版本的 newtonsoft.json 包上执行(错误从 v11.0.2 开始,然后我更新到 v12.0.1,错误仍然存在)。 API 数据是从其中检索并按预期工作,并以正确的格式返回数据。 调试器没有显示堆栈跟踪,但确实说错误通常是由本机单声道代码或依赖项使用的本机代码引起的。
如果有人需要更多信息,我很乐意提供,因为我无法在 google 上找到有关如何解决此问题的任何信息。
该错误也出现在所有模拟器上(从 512mb 到 2gb 内存,堆大小和渲染器不同。我无法使用物理设备进行测试,因为网络仍处于锁定状态,并且设备无法连接)
更新;它是固定的(我认为)。 20-12-2018
我在 API 端显式构建对象并将它们作为相应类型的对象(即 Product、Order 等)而不是 var 发送。
在反序列化、重新序列化并再次重复之后,我最终得到了一个有效但效率极低的解决方案。
之后,我在模型的属性上剪切了几个自定义 getter 和 setter。 (这绝不是这个问题的指定原因,但它帮助解决了这个问题。)
它仍然有效,然后我尝试使用问题中显示的原始代码行,它有效。
注意,我确实重新安装了 Visual Studio 两次..(一次从 15.9.2 更新到 15.9.3,昨天卸载它并安装了新的更新,15.9.4)。
这是在旧分支上完成的,该分支仍然具有所有依赖项的原始版本。
总而言之,这个错误应该不是反序列化对象不匹配的错误导致的。这样的错误应该作为反序列化错误或类似的东西抛出,而不是抛出原生单声道展开错误。
(导致此错误的代码行被两个嵌套的 try-catch 块包围..)
更新..又发生了 21-12-2018
所以昨天错误消失了。我希望它是好的,但现在它再次发生。我将其缩小到产品型号。 (由于最初的错误是在加载产品和加载历史订单时发生的,它们只共享相同的 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;有用。有接盘侠吗? 笔记;我更新了问题的名称以更具体地针对这个新问题。
【问题讨论】:
-
请具体说明:不要说“x 的最后 2 个版本”,明确提及这 2 个版本
-
你用的是最新版的VS和xamarin.forms吗?请查看此链接:stackoverflow.com/questions/46214899/…
-
@knocte 在我的回答中添加了它
-
@BillyLiu-MSFT VS 2017 最新 (15.9.3) 更新。 (尽管错误始于 15.9.2)。我检查了链接,它引发了相同的 Signal abort 错误,但由于不同的原因,链接中的错误似乎是由内存堆错误引起的。我的有点不同。很遗憾。
-
那么有没有没有问题的 JSON.Net 版本?
标签: c# android json xamarin mono