-1

I have two methods from two different third party libraries:

Task WriteToAsync(Stream stream);
Task LoadAsync(Stream stream);

I need to pipe data from source WriteTo method to Load method.

Currently next solution is used:

using (var stream = new MemoryStream()) {
    await source.WriteToAsync(stream);
    stream.Position = 0;
    await destination.LoadAsync(stream);
}

Is there any better way?

Oleg Oshkoderov
  • 500
  • 1
  • 4
  • 17
  • Rather then reading *everything* synchronously into `MemoryStream` and then writing it somewhere, you need some `async` implementation of `Stream`. You can implement one and see which virtual methods you can override to avoid having a huge buffer in between. – Sinatr Nov 20 '17 at 16:09
  • @Sinatr, That is what I'm asking, if there is any ready made implementation that I can use. – Oleg Oshkoderov Nov 20 '17 at 16:15
  • I don't know one and recommending implementations is an off-topic here. Try to ask/search for specific question instead: if libraries are popular someone may run into same problem already. Have you been [here](https://stackoverflow.com/a/1540799/1997232) (googling for "C# async stream")? – Sinatr Nov 20 '17 at 16:21

1 Answers1

1

As the code below demonstrates, you can use pipe streams to stream data from one to the other, and you should not use await on the writer until after you have started the reader.

class Program
{
   static void Main(string[] args)
   {
      ReaderDemo rd = new ReaderDemo();
      GenPrimes(rd).ContinueWith((t) => {
         if (t.IsFaulted)
            Console.WriteLine(t.Exception.ToString());
         else
            Console.WriteLine(rd.value);
      }).Wait();
   }

   static async Task GenPrimes(ReaderDemo rd)
   {
      using (var pout = new System.IO.Pipes.AnonymousPipeServerStream(System.IO.Pipes.PipeDirection.Out))
      using (var pin = new System.IO.Pipes.AnonymousPipeClientStream(System.IO.Pipes.PipeDirection.In, pout.ClientSafePipeHandle))
      {
         var writeTask = WriterDemo.WriteTo(pout);

         await rd.LoadFrom(pin);
         await writeTask;
      }
   }
}

class ReaderDemo
{
   public string value;

   public Task LoadFrom(System.IO.Stream input)
   {
      return Task.Run(() =>
      {
         using (var r = new System.IO.StreamReader(input))
         {
            value = r.ReadToEnd();
         }
      });
   }
}

class WriterDemo
{
   public static Task WriteTo(System.IO.Stream output)
   {
      return Task.Run(() => {
         using (var writer = new System.IO.StreamWriter(output))
         {
            writer.WriteLine("2");
            for (int i = 3; i < 10000; i+=2)
            {
               int sqrt = ((int)Math.Sqrt(i)) + 1;
               int factor;
               for (factor = 3; factor <= sqrt; factor++)
               {
                  if (i % factor == 0)
                     break;
               }
               if (factor > sqrt)
               {
                  writer.WriteLine("{0}", i);
               }
            }
         }
      });
   }
}
BlueMonkMN
  • 25,079
  • 9
  • 80
  • 146