Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C# chaining methods using streams

Tags:

c#

I have two different objects in c# that expose methods using streams.

One of them exposes a method that takes a Stream as a parameter and writes to the stream, while the other exposes a method that takes a Stream as a parameter and reads from it.

Writing stuff to a MemoryStream is out of the question as there is too much data to keep completely in memory. Is there a way I can somehow chain these two methods, or do I have to manually write an adaptor of some kind to go in between myself?

Edit:

one of the methods looks like this, which serializes the object to a stream:

object1.WriteToStream(Stream s)

while the other looks like this:

object2.Process(Stream input, Stream output)

The second method reads from the input stream, processes the data and writes it to another stream. My problem is that I need to use the 2nd method to process the data generated by the WriteToStream method of the first object.

like image 683
Cedric Mamo Avatar asked Nov 09 '22 15:11

Cedric Mamo


1 Answers

Yes you have a possibility to "chain" the two methods. But there are some prerequisite:

  • The output stream (the parameter of write stream) must be global, or reachable from both function.
  • The both function but be run on different thread, to run it synchronously. use Task.Run() or a different Thread
  • To synchronize this to thread you can use Semaphore

And here are sample code to do it. But this is not working code, it is just a skeleton

using System;
using System.Threading;

public class Example
{
    // A semaphore that simulates a limited resource pool.
    //
    private static Semaphore _pool;

    // A padding interval to make the output more orderly.
    private static int _padding;

    public static void Main()
    {
        // Create a semaphore that can satisfy up to three
        // concurrent requests. Use an initial count of zero,
        // so that the entire semaphore count is initially
        // owned by the main program thread.
        _pool = new Semaphore(0, 2);

        Thread threadWrite = new Thread(new ParameterizedThreadStart(WriterThread));
        Thread threadRead = new Thread(new ParameterizedThreadStart(ReadThread));

        threadWrite.Start(commonStream);
        threadRead.Start(commonStream);

        // Wait for half a second, to allow all the
        // threads to start and to block on the semaphore.
        Thread.Sleep(500);

        // The main thread starts out holding the entire
        // semaphore count. Calling Release(3) brings the 
        // semaphore count back to its maximum value, and
        // allows the waiting threads to enter the semaphore,
        // up to three at a time.
        //
        Console.WriteLine("Main thread calls Release(3).");
        _pool.Release(3);

        Console.WriteLine("Main thread exits.");
    }

    private static void WriterThread(object objStream)
    {
        Stream stream = (Stream)objStream;
        while (true)
        {
            // lock the semaphore, because you want to write the stream
            _pool.WaitOne();

            // your code goes here, to write the stream to some data, but not all 

            //release the pool, to indicate to the other thread, there are data in stream 
            _pool.Release();


            if (IsAllDataWritten)
                break;
        }
    }

    private static void ReadThread(object objStream)
    {
        Stream stream = (Stream)objStream;
        while (true)
        {
            // lock the semaphore, because you want to write the stream
            _pool.WaitOne();

            // your code goes here, to read and process the stream data

            //release the pool, to indicate to the other thread, there are data in stream 
            _pool.Release();


            if (AllDataIsReaded )
                break;
        }
    }
} 
like image 87
György Gulyás Avatar answered Nov 15 '22 13:11

György Gulyás