How to Asynchronously read MemoryStream

5.7k Views Asked by At

I am writing an application which involves IronRuby. I would like to update a UI element when I receive output from my ruby script, so I have set up the following:

var ScriptEngine engine = IronRuby.Ruby.CreateEngine();
MemoryStream outputStream = new MemoryStream();
engine.Runtime.IO.SetOutput(outputStream, Encoding.Default);

This redirects the output of IronRuby to a custom stream called outputStream. However, I cannot seem to figure out how to call a block of code once the stream receives new information. How could I do the equivalent of the following?

outputStream.DataReceived += (sender, e) =>
{
    // assumes I passed in the Func `processing` to my method
    processing(e.Value);
};

Thanks!

1

There are 1 best solutions below

6
Panagiotis Kanavos On

The easiest way to read asynchronously from any stream is to use ReadAsync in the same way that you would use Read :

async Task MyMethod()
{
    ...
    byteArray = new byte[1024];
    int count = await memStream.ReadAsync(byteArray, 0, 1024);
    ...
}

Typically, ReadAsync is a truly asynchronous call, ie it doesn't use a separate thread that blocks while waiting for a result. It takes advantage of asynchronous I/O completion ports to hand off the operation to the operating system and start processing again only when the OS returns some results.

MemoryStream may have a simpler implementation though as no I/O is actually involved. In fact, an asyncrhonous operation doesn't make much sense as Read will simply copy bytes from the stream to a buffer.

UPDATE

After checking the source for MemoryStream.ReadAsync it seems that ReadAsync just calls Read directly and returns a Task<int> with the number of bytes read. That means that byte copying is still done synchronously but at least MemoryStream can still be used in asynchronous methods. For example, it can be used in a form method to avoid blocking the UI thread while copying a large buffer.

This makes sense as simply copying the bytes will be faster than setting up an asynchronous operation.