Bu soruya, açık uçlu bir nesne System.IO.Stream
listesini göndermeden önce tüm listeyi ara belleğe almadan, bir nesneye akıtmanın ve diğer uçtan okumanın bir yolunu ararken ulaştım. (Özellikle Web API üzerinden MongoDB'den kalıcı nesnelerin akışını yapıyorum.)
@Paul Tyng ve @Rivers orijinal soruyu yanıtlarken mükemmel bir iş çıkardılar ve ben de onların yanıtlarını sorunum için bir kavram kanıtı oluşturmak için kullandım. Başka birinin aynı sorunla karşılaşması durumunda test konsolu uygulamamı burada yayınlamaya karar verdim.
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);
}
}
}
}
İmha edildiğinde bir istisna alabileceğinizi unutmayın, AnonymousPipeServerStream
mevcut sorunla ilgili olmadığı için bunu görmezden geldim.