如何异步读取MemoryStream

时间:2016-05-12 08:05:41

标签: c# ironruby

我正在编写涉及IronRuby的应用程序。当我从ruby脚本接收输出时,我想更新UI元素,所以我设置了以下内容:

var i = 0;
var array = document.getElementsByClassName("doTest");

function execute() {
    var dothis = function ()
    {
        try {
            $(array[i]).trigger('click');
        } catch (err) {
              clearInterval(x); 
        }
        if (i == array.length) {
            clearInterval(x);
        }
        i++;
    };
    var x = setInterval(dothis, 1);
}

$("#doAllTest").click(function () {
    execute();
});

这会将IronRuby的输出重定向到名为var ScriptEngine engine = IronRuby.Ruby.CreateEngine(); MemoryStream outputStream = new MemoryStream(); engine.Runtime.IO.SetOutput(outputStream, Encoding.Default); 的自定义流。但是,一旦流接收到新信息,我似乎无法弄清楚如何调用代码块。我怎么能做相当于以下的事情?

outputStream

谢谢!

1 个答案:

答案 0 :(得分:2)

从任何流异步读取的最简单方法是使用ReadAsync,就像使用Read一样:

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

通常,ReadAsync是一个真正的异步调用,即它不会使用在等待结果时阻塞的单独线程。它利用异步I / O完成端口将操作切换到操作系统,并仅在操作系统返回某些结果时再次开始处理。

MemoryStream可能有一个更简单的实现,因为实际上没有涉及I / O.事实上,异步操作没有多大意义,因为Read只会将字节从流复制到缓冲区。

<强>更新

检查MemoryStream.ReadAsync的来源后,似乎ReadAsync只是直接调用Read并返回一个Task<int>,其中包含读取的字节数。这意味着字节复制仍然是同步完成的,但至少MemoryStream仍可用于异步方法。例如,它可以在表单方法中使用,以避免在复制大缓冲区时阻塞UI线程。

这是有道理的,因为简单地复制字节将比设置异步操作更快。