2017-03-29 24 views
1

私は例外的に私はオンラインに関する多くの情報を見つけることができないように走っています。JSON予期しない終了

予期しない終了。行番号、位置######

いくつかの詳細は、Windows Mobile 6.5.3、Mobile .NET CE Frameworkで実行されています。私はWebサービスコールから応答を解析しています。私は応答が適切なJSONフォーマットであることを確認しましたが、私はその応答が非常に大きいことを知っています。

私が理解できないことは、私がこの腹を立てる理由です。ここに私の解析コードは、この上でいくつかの光を当てることができます誰でも

List<T> objList = new List<T>(); 
using (StreamReader sr = new StreamReader(responseStream)) 
{ 
    using (JsonTextReader jr = new JsonTextReader(sr)) 
    {    
     JsonSerializer ser = new JsonSerializer();   
     JObject jo = ser.Deserialize(jr) as JObject; //<---- This line throws the exception 
     if (jo != null) 
     {      
      List<JToken> jResults = jo[name + "Result"].Children().ToList(); 
      foreach (JToken jObjResult in jResults) 
      { 
       T obj = JsonConvert.DeserializeObject<T>(jObjResult.ToString()); 
       objList.Add(obj); 
      } 
     } 
    } 
} 
return objList; 

(はい、私たちは常に複雑なオブジェクトのリストを取得する)ですが、行ってください。ありがとう。

UPDATE:正確な例外テキストを追加

Message: "Unexpected end. Line 1, position 1594143." 
StackTrace: 
     at Newtonsoft.Json.JsonTextReader.ParseValue(Char currentChar) 
     at Newtonsoft.Json.JsonTextReader.ReadInternal() 
     at Newtonsoft.Json.JsonTextReader.Read() 
     at Newtonsoft.Json.JsonWriter.WriteToken(JsonReader reader, Int32 initialDepth) 
     at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateJObject(JsonReader reader) 
     at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateObject(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, Object existingValue) 
     at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateValueInternal(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, Object existingValue) 
     at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateValueNonProperty(JsonReader reader, Type objectType, JsonContract contract) 
     at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.Deserialize(JsonReader reader, Type objectType) 
     at Newtonsoft.Json.JsonSerializer.DeserializeInternal(JsonReader reader, Type objectType) 
     at Newtonsoft.Json.JsonSerializer.Deserialize(JsonReader reader, Type objectType) 
     at Newtonsoft.Json.JsonSerializer.Deserialize(JsonReader reader) 
     at MY CODE HIDDEN HERE 

注:正確な位置時々変化しますが、常に65536

+1

JSONのサイズはどれくらいですか?それでも解析できない最小のスニペットを投稿できますか? – mason

+0

JSONのどの時点で、#と#####の位置にありますか?たとえば、65535文字のような素晴らしい境界になる可能性はありますか?本当にもっと情報が必要です。 – DavidG

+0

逆シリアル化や 'JObject'へのキャストに問題がありますか? –

答えて

0

[OK]をより大きい数であるように思えます。私は問題の原因を突き止めましたが、接続スピードと関係しているため、再現するのは簡単ではありません。文字通り、応答ストリームがデータを供給できる速度。

変化したコード

using (StreamReader sr = new StreamReader(responseStream)) 
{ 
    using (JsonTextReader jr = new JsonTextReader(sr)) 
    { 
     while (jr.Read()) 
      if (jr.TokenType == JsonToken.StartArray) 
       break; 
     jr.Read(); 

     JsonSerializer Jser = new JsonSerializer(); 
     while (!sr.EndOfStream && jr.TokenType != JsonToken.EndArray) 
     { 
      if(jr.TokenType == JsonToken.StartObject) 
      { 
       T tobj = Jser.Deserialize<T>(jr); 
       objList.Add(tobj); 
      } 
      //consume the EndObject tag 
      if (jr.TokenType == JsonToken.EndObject) 
       jr.Read(); 
      //Deliberately slow down the process, On purpose, otherwise we will overrun the stream itself and throw an error 
      Thread.Sleep(1); //<=== VERY IMPORTANT LINE 
     } 
    } 
} 

説明

私は失敗のストリーム位置を確認することでこれを見つけました。私はそれが変化し続けていることに気付きました。そして、変更は、詳細を見てデバッグモードで一時停止したプロセスでどれくらいの時間を費やしたかに基づいていることがわかりました。私が過ごす時間が長くなればなるほど、読んだほうが遠くになるでしょう。だから、ストリームを手動で1つずつ移動させるように変更しました(これもいくつかの処理を行いましたが、トークンの順序がどうなるかを理解しました)。非常に短いスレッドスリープに追加されました。そしてそれは完璧に働いた。

したがって、要約します。遅い接続で応答ストリームから直接JSONをロードするときは、実際にデータをシリアル化して、応答ストリームより速くシリアル化できます。この場合、「予期しない終了」が報告されます。

+0

JSONをロードしているときに、JSONをシリアル化していない場合、JSONをデシリアライズしています。 –

+1

IMHO、99%で、Thread.Sleep()はコードを動作させるには間違っています。 –

+0

タスクでこれを行う場合は、 'task.delay'と一緒に行くことができます。 – mcy

関連する問題