如何在C#8.0中使用异步流

异步编程已经存在了一段时间。 .NET中引入了async和await关键字,使我们能够编写可以轻松利用异步优势的程序。 但是,直到IAsyncEnumerable <T>在C#8.0中出现之前,还没有任何方法可以异步使用数据流。

IAsyncEnumerable <T>与用于迭代集合的IEnumerable <T>方法类似,不同之处在于IAsyncEnumerable <T>允许我们异步遍历该集合。 换句话说,IAsyncEnumerable <T>允许我们在不阻塞线程的情况下等待集合中的下一个元素。

[ 同样在InfoWorld上:TypeScript与JavaScript:了解差异 ]

在本文中,我们将通过相关的代码示例来了解IAsyncEnumerable <T>解决的挑战。 若要使用本文提供的代码示例,您应该在系统中安装Visual Studio 2019。 如果您还没有副本,则可以在此处下载Visual Studio 2019

在Visual Studio 2019中创建控制台应用程序项目

首先,让我们在Visual Studio中创建一个.NET Core控制台应用程序项目。 假设系统中已安装Visual Studio 2019,请按照以下概述的步骤在Visual Studio 2019中创建新的.NET Core控制台应用程序项目。

  1. 启动Visual Studio IDE。
  2. 点击“创建新项目”。
  3. 在“创建新项目”窗口中,从显示的模板列表中选择“控制台应用程序(.NET Core)”。
  4. 点击下一步。
  5. 在接下来显示的“配置新项目”窗口中,指定新项目的名称和位置。
  6. 单击创建。

这将在Visual Studio 2019中创建一个新的.NET Core控制台应用程序项目。在本文的后续部分中,我们将使用该项目来处理IAsyncEnumerable <T>和异步流。

在Visual Studio 2019中指定语言版本

为了能够在Visual Studio中使用C#8.0,必须像我们所做的那样使用针对.NET Core的项目。 您还需要更改项目中使用的语言的语言版本。 为此,请按照以下概述的步骤操作:

  1. 右键单击该项目。
  2. 选择“属性”以调用属性窗口。
  3. 单击构建->高级。
  4. 单击语言版本的下拉控件。
  5. 选择C#8.0作为语言版本。
  6. 单击确定。

在C#8.0中的IAsyncDisposable,IAsyncEnumerable <T>和IAsyncEnumerator <T>

异步流使您可以异步使用数据流。 在.NET Standard 2.1版本中引入了接口IAsyncDisposable,IAsyncEnumerable <T>和IAsyncEnumerator <T>。 这些接口使我们能够使用异步流。 以下代码段显示了这三个接口的代码。

public interface IAsyncDisposable
{
    ValueTask DisposeAsync();
}
public interface IAsyncEnumerable<out T>
{
    IAsyncEnumerator<T> GetAsyncEnumerator(CancellationToken
    token = default);
}
public interface IAsyncEnumerator<out T> : IAsyncDisposable
{
    ValueTask<bool> MoveNextAsync();
    T Current { get; }
}

[ 也在InfoWorld上:2020年探索的5种Microsoft开发人员工具和技术 ]

为什么要使用异步流?

想象一下,您有一个数据访问库,该库从数据存储中读取数据并一次性发送回所有结果。 您可以轻松实现这种方法。 您需要做的只是进行一些异步调用,以从基础数据存储中获取数据,然后立即返回所有数据。

只要您不需要在页面中返回数据,此解决方案就可以了。 在这种情况下,您可能必须进行多次调用才能返回数据。 在这方面,最好的解决方案是您可以在数据可用后立即将其发送回调用方。

这正是异步流可以拯救的地方。 如果返回数据的方法是同步的,则可以将yield return语句与IEnumerable <T>一起使用。 但是,此解决方案无法扩展,因为它将导致阻塞调用。

最好的解决方案是在返回IAsyncEnumerable <T>的异步方法中使用yield return。 返回异步流的方法将返回IAsyncEnumerable <T>的实例,并包含一个或多个yield return语句。

在C#8.0中创建异步流

下面的代码段说明了一个异步方法,该方法返回Task <IEnumerable <T >>。

class Program
    {
        const int DELAY = 1000;
        const int MIN = 1;
        const int MAX = 10;
        static async Task Main(string[] args)
        {
            foreach (int number in await GetData())
            {
                Console.WriteLine(number);
            }
            Console.ReadLine();
        }
        static async Task<IEnumerable<int>> GetData()
        {
            List<int> integers = new List<int>();
            for (int i = MIN; i <= MAX; i++)
            {
                await Task.Delay(DELAY);
                integers.Add(i);
            }
            return integers;
        }
    }

执行此应用程序时,它将等待10秒钟,然后在控制台窗口中显示1到10之间的所有数字。 尽管GetData方法是异步的,但是此代码将一次返回所有这些数字,而不是一一生成就一一返回。

[ 同样在InfoWorld上:如何在ASP.NET Web API中记录请求和响应元数据 ]

这就是yield关键字的用处。yield关键字(在C#2.0中引入)可以执行有状态迭代,并逐个返回集合的每个元素。 在返回数据之前,无需创建临时集合来存储数据。

以下代码段显示了如何修改GetData方法以合并yield关键字。

static async IAsyncEnumerable<int> GetData()
{
   for (int i = MIN; i < MAX; i++)
   {
      yield return i;
      await Task.Delay(DELAY);  
   }
}

在C#8.0中使用异步流

使用异步流时,需要指定await关键字,然后指定foreach关键字。 您可以从Main方法调用上述示例中的方法,如下面的代码片段所示。

static async Task Main(string[] args)
{
    await foreach (int number in GetData())
    {
        Console.WriteLine(number);
    }
  Console.ReadLine();
}

这是完整的程序供您参考。

using System;
using System.Collections.Generic;
using System.Threading.Tasks;
namespace Test
{
    class Program
    {
        const int DELAY = 1000;
        const int MIN = 1;
        const int MAX = 10;
        static async Task Main(string[] args)
        {
            await foreach (int number in GetData())
            {
                Console.WriteLine(number);
            }
            Console.ReadLine();
        }
        static async IAsyncEnumerable<int> GetData()
        {
            for (int i = MIN; i < MAX; i++)
            {
                yield return i;
                await Task.Delay(DELAY);  
            }
        }
    }
}

[ 通过InfoWorld Daily新闻通讯了解软件开发,云计算,数据分析和机器学习方面的最新发展 ]

对IAsyncEnumerable <T>(又名异步流)的支持是C#8.0中最重要的新功能之一。 您可以在应用程序中利用异步流来使代码更整洁,更高效和高性能。 若要使用C#8.0编译器,您将需要Visual Studio 2019版本16.3或.NET Core 3.0 SDK。

From: https://www.infoworld.com/article/3531251/how-to-use-asynchronous-streams-in-csharp-80.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值