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!
The easiest way to read asynchronously from any stream is to use ReadAsync in the same way that you would use
Read:Typically,
ReadAsyncis 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
Readwill simply copy bytes from the stream to a buffer.UPDATE
After checking the source for MemoryStream.ReadAsync it seems that
ReadAsyncjust callsReaddirectly and returns aTask<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.