2014-10-09 6 views
6

का उपयोग कर जेएसओएन प्रारूप के रूप में डेटा की बड़ी सूची स्ट्रीमिंग एमवीसी मॉडल का उपयोग करके, मैं एक जेसनआरसल्ट लिखना चाहता हूं जो जेसन स्ट्रिंग को क्लाइंट को स्ट्रीम करेगा, ताकि सभी डेटा जेसन स्ट्रिंग में एक बार में परिवर्तित हो सके और फिर स्ट्रीमिंग हो सके यह वापस ग्राहक के लिए। मेरे पास ऐसे क्रियाएं हैं जिनके लिए जेसन स्थानांतरण के रूप में बहुत बड़ा (300,000 से अधिक रिकॉर्ड) भेजने की आवश्यकता है और मुझे लगता है कि मूल जेसनआरसल्ट कार्यान्वयन स्केलेबल नहीं है।जेसननेट

मैं जेसननेट का उपयोग कर रहा हूं, मुझे आश्चर्य है कि जेसन स्ट्रिंग के हिस्सों को स्ट्रीम करने का कोई तरीका है क्योंकि इसे बदल दिया जा रहा है।

//Current implementation: 
response.Write(Newtonsoft.Json.JsonConvert.SerializeObject(Data, formatting)); 
response.End(); 

//I know I can use the JsonSerializer instead 
Newtonsoft.Json.JsonSerializer serializer = new Newtonsoft.Json.JsonSerializer(); 
serializer.Serialize(textWriter, Data); 

हालांकि मुझे यकीन है कि मैं कैसे हिस्सा textWriter में लिखा हो और प्रतिक्रिया में लिख सकते हैं और reponse.Flush कॉल कर सकते हैं() जब तक सभी 3,00,000 रिकॉर्ड Json में बदल दिए जाते नहीं हूँ।

क्या यह संभव है?

उत्तर

12

अपना अंतिम आउटपुट मानना ​​एक JSON सरणी है और प्रत्येक "खंड" उस सरणी में एक आइटम है, तो आप निम्न कक्षा की तरह कुछ कोशिश कर सकते हैं। यह आउटपुट स्ट्रीम में JSON लिखने के लिए JsonTextWriter का उपयोग करता है, और JObject का उपयोग लेखक को लिखने से पहले व्यक्तिगत रूप से प्रत्येक आइटम को क्रमबद्ध करने के साधन के रूप में करता है। आप को IEnumerable कार्यान्वयन पास कर सकते हैं जो आपके डेटा स्रोत से अलग-अलग आइटम पढ़ सकते हैं ताकि आपके पास उन्हें एक ही समय में स्मृति में न हो। मैंने इस बड़े पैमाने पर परीक्षण नहीं किया है, लेकिन आपको सही दिशा में जाना चाहिए।

public class JsonStreamingResult : ActionResult 
{ 
    private IEnumerable itemsToSerialize; 

    public JsonStreamingResult(IEnumerable itemsToSerialize) 
    { 
     this.itemsToSerialize = itemsToSerialize; 
    } 

    public override void ExecuteResult(ControllerContext context) 
    { 
     var response = context.HttpContext.Response; 
     response.ContentType = "application/json"; 
     response.ContentEncoding = Encoding.UTF8; 

     JsonSerializer serializer = new JsonSerializer(); 

     using (StreamWriter sw = new StreamWriter(response.OutputStream)) 
     using (JsonTextWriter writer = new JsonTextWriter(sw)) 
     { 
      writer.WriteStartArray(); 
      foreach (object item in itemsToSerialize) 
      { 
       JObject obj = JObject.FromObject(item, serializer); 
       obj.WriteTo(writer); 
       writer.Flush(); 
      } 
      writer.WriteEndArray(); 
     } 
    } 
} 
+0

बहुत आशाजनक लगता है ... मैं इसे आज़माने और यू पता है कि यह कैसे जाता है दूँगी ... – sam360

+0

समाधान काम किया जो स्मृति अपवाद से बाहर होने से बचाता है और उस अद्भुत है। लेकिन मुझे लगता है कि अगर रिकॉर्ड के बैचों को एक-एक करके एक साथ फ्लश किया जाएगा तो यह अधिक अनुकूलित होगा। सुनिश्चित नहीं है कि इष्टतम संख्या क्या है! – sam360

+0

हाँ, मैंने इसके बारे में भी सोचा। आप JsonStreamingResult को आसानी से एक काउंटर जोड़ सकते हैं जो इसे फ्लश तक प्रतीक्षा करने का कारण बनता है जब तक कि कुछ संख्याओं को गणित से पढ़ा नहीं जाता है। यदि स्थिति के आधार पर संख्या अलग है, तो आप इसे एक पैरामीटर बना सकते हैं ताकि आप इसे प्रत्येक अलग-अलग उपयोग के लिए ट्यून कर सकें। साथ ही, IENumerable पक्ष पर, आप बैच में अपने डेटा स्रोत से पूछने के साथ-साथ दक्षता में सुधार करने के लिए एक तंत्र को कार्यान्वित कर सकते हैं। हालांकि आपको सबसे अच्छा काम करने के लिए बहुत सारे मापने और परीक्षण करना होगा। –