I have tried to pass stream as an argument but I am not sure which way is "the best" so would like to hear your opinion / suggestions to my code sample
I personally prefer Option 3, but I have never seen it done this way anywhere else.
Option 1 is good for small streams (and streams with a known size)
Option 2_1 and 2_2 would always leave the "Hander" in doubt of who has the responsibility for disposing / closing.
public interface ISomeStreamHandler
{
    // Option 1
    void HandleStream(byte[] streamBytes);
    // Option 2
    void HandleStream(Stream stream);
    // Option 3
    void HandleStream(Func<Stream> openStream);
}
public interface IStreamProducer
{
    Stream GetStream();
}
public class SomeTestClass
{
    private readonly ISomeStreamHandler _streamHandler;
    private readonly IStreamProducer _streamProducer;
    public SomeTestClass(ISomeStreamHandler streamHandler, IStreamProducer streamProducer)
    {
        _streamHandler = streamHandler;
        _streamProducer = streamProducer;
    }
    public void DoOption1()
    {
        var buffer = new byte[16 * 1024];
        using (var input = _streamProducer.GetStream())
        {
            using (var ms = new MemoryStream())
            {
                int read;
                while ((read = input.Read(buffer, 0, buffer.Length)) > 0) 
                {
                    ms.Write(buffer, 0, read);
                }
                _streamHandler.HandleStream(ms.ToArray());
            }
        }
    }
    public void DoOption2_1()
    {
        _streamHandler.HandleStream(_streamProducer.GetStream());
    }
    public void DoOption2_2()
    {
        using (var stream = _streamProducer.GetStream())
        {
            _streamHandler.HandleStream(stream);    
        }
    }
    public void DoOption3()
    {
        _streamHandler.HandleStream(_streamProducer.GetStream);
    }
}