1

我一直在想...

新的 Async 结构实际上是否允许中间结果,而无需在消费者端编写新代码?

让我用一个例子来详细说明。

假设我们有一个方法可以将数据下载到字节数组或流中,以哪个更好。

是否有可能,await在下载完成之前,使用内置异步功能的方法可以开始使用字节数组或流?我可以做的是每次下载流的某个部分时引发事件,但这会再次增加混乱。

让我写一个代码示例(从我的脑海中,不会是正确的代码!)我(会)期望产生中间结果,因为awaited 方法返回这样的结果。

io.Stream data = await downloadData();
byte[4096] buffer = new byte[4096];
while (!data.EOF) {
  (await?) data.Read(buffer, offset, 4096);
}

到目前为止,Stream.Read不能等待,但是我们有什么方法可以做到这一点吗?我希望能够await通过转账。我在监督什么吗?

4

2 回答 2

2

我对它不太熟悉,无法给你一个很好的例子,但因为听起来你不想要一次性结果,而是想要多个结果,这听起来更适合 observable。此处输入的链接描述是来自 Rx 团队的 2.0 beta 博客文章的图像,在这些方面非常有用(恕我直言)。

在此处输入图像描述

于 2012-05-11T19:22:57.367 回答
2

如果你Stream在 .Net 4.5 中使用,你可以使用它的ReadAsync()方法:

Stream stream = await downloadData();
byte[4096] buffer = new byte[4096];
int read;
do
{
    read = await stream.ReadAsync(buffer, 0, buffer.Length);
    // do something with buffer here
} while (read > 0);

如果您的意思是您的流没有诸如 之类的方法,但确实支持使用,模式ReadAsync()的异步,并且您想使用,那么您也可以这样做:BeginXxx()EndXxx()await

do
{
    read = await Task.Factory.FromAsync<byte[], int, int, int>(
        stream.BeginRead, stream.EndRead, buffer, 0, buffer.Length, null);
    // do something with buffer here
} while (read > 0);

但是,如果您只有一个同步Read()方法,那么使用它的唯一方法是在后台线程上async启动一个新方法:Task

do
{
    read = await Task.Run(() => stream.Read(buffer, 0, buffer.Length));
    // do something with buffer here
} while (read > 0);

这段代码的问题是它仍然阻塞了一个线程,这async是试图避免的。但如果该方法在 GUI 线程上运行,并且您不能在后台线程上运行整个循环,它可能仍然有用。

于 2012-05-11T11:28:41.110 回答