Saya tiba di pertanyaan ini mencari cara untuk melakukan streaming daftar objek terbuka ke System.IO.Stream
dan membacanya dari ujung yang lain, tanpa buffering seluruh daftar sebelum mengirim. (Khususnya saya streaming objek tetap dari MongoDB melalui Web API.)
@ Paul Tyng dan @Rivers melakukan pekerjaan yang sangat baik untuk menjawab pertanyaan awal, dan saya menggunakan jawaban mereka untuk membangun bukti konsep untuk masalah saya. Saya memutuskan untuk memposting aplikasi konsol pengujian saya di sini kalau-kalau ada orang lain yang menghadapi masalah yang sama.
using System;
using System.Diagnostics;
using System.IO;
using System.IO.Pipes;
using System.Threading;
using System.Threading.Tasks;
using Newtonsoft.Json;
namespace TestJsonStream {
class Program {
static void Main(string[] args) {
using(var writeStream = new AnonymousPipeServerStream(PipeDirection.Out, HandleInheritability.None)) {
string pipeHandle = writeStream.GetClientHandleAsString();
var writeTask = Task.Run(() => {
using(var sw = new StreamWriter(writeStream))
using(var writer = new JsonTextWriter(sw)) {
var ser = new JsonSerializer();
writer.WriteStartArray();
for(int i = 0; i < 25; i++) {
ser.Serialize(writer, new DataItem { Item = i });
writer.Flush();
Thread.Sleep(500);
}
writer.WriteEnd();
writer.Flush();
}
});
var readTask = Task.Run(() => {
var sw = new Stopwatch();
sw.Start();
using(var readStream = new AnonymousPipeClientStream(pipeHandle))
using(var sr = new StreamReader(readStream))
using(var reader = new JsonTextReader(sr)) {
var ser = new JsonSerializer();
if(!reader.Read() || reader.TokenType != JsonToken.StartArray) {
throw new Exception("Expected start of array");
}
while(reader.Read()) {
if(reader.TokenType == JsonToken.EndArray) break;
var item = ser.Deserialize<DataItem>(reader);
Console.WriteLine("[{0}] Received item: {1}", sw.Elapsed, item);
}
}
});
Task.WaitAll(writeTask, readTask);
writeStream.DisposeLocalCopyOfClientHandle();
}
}
class DataItem {
public int Item { get; set; }
public override string ToString() {
return string.Format("{{ Item = {0} }}", Item);
}
}
}
}
Perhatikan bahwa Anda mungkin menerima pengecualian saat AnonymousPipeServerStream
dibuang, saya mengabaikannya karena tidak relevan dengan masalah yang dihadapi.