I have a class that does some long-running processing with lots of data and writes the output to a stream that I provide. I am trying to put a WCF front on this (using named pipes) but having trouble figuring out how to return the stream. I have something like this so far:
interface IProcessor { Stream GetStream(); }
class Host {
static void Main(string[] args) {
using (ServiceHost sh = new ServiceHost(typeof(Processor), new Uri[]{new Uri("net.pipe://localhost")})) {
var binding = new NetNamedPipeBinding();
binding.TransferMode = TransferMode.StreamedResponse;
sh.AddServiceEndpoint(typeof(IProcessor), binding, "foo");
sh.Open();
Console.WriteLine("Waiting...");
Console.ReadLine();
sh.Close();
}
}
}
class Processor : IProcessor {
Stream GetStream() {
var SourceProcessor = new SourceProcessor(...);
var s = new MemoryStream();
new Task(() => { SourceProcessor.Run(s); }).Start();
return s;
}
}
class Client {
static void Main(string[] args) {
Console.WriteLine("Starting...");
var binding = new NetNamedPipeBinding();
binding.TransferMode = TransferMode.StreamedResponse;
ChannelFactory<IProcessor> f = new ChannelFactory<IProcessor>(binding, new EndpointAddress("net.pipe://localhost/foo"));
Console.WriteLine("Creating channel...");
IProcessor eps = f.CreateChannel();
Console.WriteLine("Getting stream.");
Stream s = eps.GetStream();
StreamReader sr = new StreamReader(s);
while (!sr.EndOfStream) Console.WriteLine(sr.ReadLine());
Console.ReadLine();
}
}
Everything goes through the motions but of course none of the source data makes it through to the client. I'm confused as to how I can do this (maybe I can't) since I need to both return the stream and run the task and potentially wait for the task to finish. If I just call SourceProcessor.Run(s) without being in a task, it would block and buffer, allegedly, but I'm not sure how to make it wait until the task is done while also returning the stream for the client to read...