简体   繁体   English

json反序列化导致dotnet核心应用程序中止 - 不会抛出任何异常

[英]json deserialization causes dotnet core application to abort - no exceptions are thrown

I have a very trivial method for deserialization of data from a file: 我有一个非常简单的方法来反序列化文件中的数据:

private static List<DataJSON> LoadJSON()
{

    List<DataJSON> jsonData = new List<DataJSON>();
    /*
    using (StreamReader file = File.OpenText(@"actions.json"))
    {
        JsonSerializer serializer = new JsonSerializer();
        jsonData = (List<DataJSON>)serializer.Deserialize(file, typeof(List<DataJSON>));
    }*/

    Console.WriteLine("a");
    var file = File.ReadAllText("actions.json");
    Console.WriteLine("b");
    try
    {
        jsonData = JsonConvert.DeserializeObject<List<DataJSON>>(file);
    }
    catch (Exception ex)
    {
        Console.WriteLine(ex.Message);
    }
    Console.WriteLine("c");
    return jsonData;
}

Which is working just fine on Windows machine. 哪个在Windows机器上工作得很好。 However, on linux (Debian 9) I am getting "Aborts". 但是,在linux(Debian 9)上我得到了“Aborts”。 There is no exception thrown at all: 没有异常抛出:

在此输入图像描述

I have placed some additional console line outputs, and managed to track down the issue to this line: 我已经放置了一些额外的控制台线路输出,并设法追踪到这一行的问题:

List<DataJSON> jsonData = JsonConvert.DeserializeObject<List<DataJSON>>

is it possible for the dotnet to output something more meaningful than "Aborted"? 是否有可能让dotnet输出比“Aborted”更有意义的东西? What could be the cause of this issue? 这个问题可能是什么原因?

App is compiled like this: 应用程序编译如下:

dotnet publish -c release --runtime linux-x64 dotnet发布-c发布--runtime linux-x64

Also dotnet --version command output: 还有dotnet --version命令输出:

2.1.3 2.1.3

Edit: As it turns out - the issue is totally random. 编辑:事实证明 - 问题完全是随机的。 The JSON is de-serialized 3 times out of 10. Or 5 out of 10. It either works or not - randomly. JSON在10次中被反序列化3次。或者10次中的5次。它可以工作或不工作 - 随机。

Edit 2. As it turns out - this issue has very little in common with Deserialization. 编辑2.事实证明 - 这个问题与反序列化几乎没有共同之处。 The problem is the type of the object that is being de-serialized. 问题是被反序列化的对象的类型。 I was able to reproduce the issue on multiple occasions just by doing this: 通过这样做,我能够在多个场合重现这个问题:

static void Main(string[] args)
{
    Console.WriteLine("Start");

    List<string> symbolsStr = new List<string>() {
        "MODETH", "MTHETH", "MTLETH", "NANOETH", "NAVETH", "NEBLETH", "NEOETH",
        "NULSETH", "OAXETH", "OMGETH", "OSTETH", "PIVXETH", "POEETH", "POWRETH",
        "MDAETH", "PPTETH", "QTUMETH", "RCNETH", "RDNETH", "REQETH", "RLCETH",
        "SALTETH", "SNGLSETH", "SNMETH", "SNTETH", "STEEMETH", "STORJETH", "STRATETH",
        "SUBETH", "TNBETH", "QSPETH", "TNTETH", "MCOETH", "LUNETH", "CNDETH"};

    foreach (var item in symbolsStr)
    {
        var symbol = (Symbol)item;
    }

    Console.WriteLine("End");
    Environment.Exit(0);
}

When the string is converted to Symbol type of object - Abort is happening (presumably). string转换为Symbol类型的对象时 - 正在发生中止(推测)。 The causes of it are unknown to me. 它的原因我不知道。 Also, the reason why exception is not shown is also unknown. 此外,未显示异常的原因也是未知的。 I'd still appreciate to hear out any advices on how to debug this issue. 我仍然希望听到有关如何调试此问题的任何建议。 In a meanwhile - I have contacted the creator of a library (C# Binance API by sonvister) which seems to be misbehaving on my machine. 与此同时 - 我已经联系了图书馆的创建者(sonvister的C#Binance API),这似乎在我的机器上行为不端。 I will keep this post updated. 我会更新此帖子。

If you want the information from the exception you can try to throw it: 如果您想要异常中的信息,可以尝试throw它:

catch (Exception ex)
{
    Console.WriteLine(ex.Message);
    throw ex; 
}

I have got a partial answer to my question. 我对我的问题得到了部分答复。

Problem description 问题描述

As you know, there is an type-safe Enum pattern out there . 如你所知,有一个类型安全的Enum出模式存在 The JSON that I was trying to deserialize - had objects of such type( Symbol ) serialized. 我试图反序列化的JSON - 将这种类型的对象( Symbol )序列化。 Abortion happenned at the time when code tried to access Symbol object instance (or convert string to Symbol type). 当代码尝试访问Symbol对象实例(或将string转换为Symbol类型)时发生堕胎。

The main class had following structure (extremely simplified version): 主类有以下结构(极简版):

public sealed class Symbol
{
    public static readonly Symbol ONE = new Symbol(new[] { OrderType.Limit, OrderType.LimitMaker, OrderType.Market, OrderType.StopLossLimit, OrderType.TakeProfitLimit });
    public static readonly Symbol TWO = new Symbol(new[] { OrderType.Limit, OrderType.LimitMaker, OrderType.Market, OrderType.StopLossLimit, OrderType.TakeProfitLimit });
    public static readonly Symbol THREE = new Symbol(new[] { OrderType.Limit, OrderType.LimitMaker, OrderType.Market, OrderType.StopLossLimit, OrderType.TakeProfitLimit });
    // 264 such lines in total

    public Symbol(IEnumerable<OrderType> orderTypes)
    {

    }
}

After hours of testing I managed to track down the issue to the fact, that when half of Symbol s are removed from the main class, then the problem goes away. 经过几个小时的测试后,我设法找到了这个问题,当一半的Symbol从主类中移除时,问题就消失了。 It doesn't matter exactly which symbols are removed as long as it's noticeable amount. 只要它是明显的数量,确切地删除哪些符号并不重要。

I have then determined, then anonymous type of objects are causing this issue, by randomly changing the parameter type to List . 我已经确定,然后匿名类型的对象导致此问题,通过随机将参数类型更改为List

Ie instead of this: 即代替这个:

new[] { OrderType.Limit, OrderType.LimitMaker, OrderType.Market, OrderType.StopLossLimit, OrderType.TakeProfitLimit }

I used this: 我用过这个:

new List<OrderType> { OrderType.Limit, OrderType.LimitMaker, OrderType.Market, OrderType.StopLossLimit, OrderType.TakeProfitLimit }

That was when the issue was finally resolved. 那是问题最终得到解决的时候。

Test approach 测试方法

Console app (.net core 2.x): 控制台应用程序(.net core 2.x):

 static void Main(string[] args)
 {
      var symbol = Symbol.ONE;
 }

Compilation command: 编译命令:

dotnet publish -c release -r debian-x64 dotnet发布-c release -r debian-x64

Linux command for testing: 用于测试的Linux命令:

while sleep 0.5 ; 睡觉0.5; do dotnet BinanceTestConsole.dll ; 做dotnet BinanceTestConsole.dll; done DONE

The linux command will execute dotnet application once in half-a-second time. linux命令将在半秒钟内执行一次dotnet应用程序。 Therefore, if at least one "Aborted" is printed within 20 second interval - you can consider the test as not passed. 因此,如果在20秒间隔内至少打印一个“已中止” - 您可以认为测试未通过。

Final words 最后的话

Now, I don't know exactly what the issue is. 现在,我不知道究竟是什么问题。 It probably has something to do with how .net core handles anonymous object conversion to other types of objects or something completely different. 它可能与.net核心如何处理匿名对象转换为其他类型的对象或完全不同的东西有关。 This resolution also does not provide any information about exception is (presumably) being thrown at a run time. 此解决方案也不提供有关异常的任何信息(可能)在运行时抛出。 My suggestion for anybody who's having the same issue - get the source of the library that is throwing the error - and try to strip down the code until there is nothing but bones, and the error is still thrown! 我对任何有同样问题的人的建议 - 获取抛出错误的库的源代码 - 并尝试删除代码直到除了骨头之外什么都没有,并且仍然抛出错误! Corner it and fight it! 转过来对抗吧! Hopefully you will find the answer. 希望你会找到答案。 Then file a report to Microsoft (/git). 然后向Microsoft(/ git)提交报告。

Edit: 编辑:

OrderType[] has the same result as if new[] was used.. So probably it has nothing to do with anonymous object.. but an array? OrderType[]与使用new[] OrderType[]具有相同的结果。所以可能它与匿名对象无关......但是数组? Hm HM

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

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