c# - 新 Async/Await 命令中的中间结果

标签 c# asynchronous async-await .net-4.5 c#-5.0

我一直在想...

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

让我举个例子。

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

是否有可能,await 所述方法可以在下载完成之前使用内置异步功能开始使用字节数组或流?我能做的是在每次下载流的特定部分时引发事件,但这又增加了困惑。

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

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

截至目前,Stream.Readnot 可等待的,但是我们有什么方法可以做到这一点吗?我希望能够通过传输await。我在监督什么吗?

最佳答案

如果您在 .Net 4.5 中使用 Stream,您可以使用它的 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 线程上运行,并且您不能在后台线程上运行整个循环,它可能仍然有用。

关于c# - 新 Async/Await 命令中的中间结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10549683/

相关文章:

c# - 如何在 sitecore 中获取子孙

ios - 在 Swift 中等待异步操作完成

c++ - 游戏逻辑的异步屏幕更新,C++

programming-languages - 同步与异步语言

c# - 恢复另一个应用程序的最小化窗口

c# - kernel32.dll SetEnvironmentVariable 中的 EntryPointNotFoundException

javascript - 如何正确等待 ES6 Javascript 异步函数的解析值?

c# - await 将 HttpContext.Current 设置为 null/prior - 无法手动设置

javascript - 等待 AngularJS 或 Javascript(浏览器)中的异步数据

c# - Visual Studio C# 2008 : Code Folding Problem when Typing