使用.NET C#7和VS 2017使用EventHubConsumerClient检查发送的S2C消息

问题描述

我从IoT中心和Azure服务开始。我正在关注此快速入门教程:Quickstart: Send telemetry from a device to an IoT hub and read it with a back-end application (.NET)

created a Free Tier IoT Hub用我的Azure帐户,registered a device使用Azure Cloud Shell。现在,我正在开发一个“入门”库send D2C messages,可以看到read sent messages是可能的。我在最后一步遇到问题,似乎代码是用C#8编写的,但是我正在使用VS 2017进行开发,并且在await foreach循环中遇到错误

示例代码here,这是我要更改为C#7的代码

private static async Task ReceiveMessagesFromDeviceAsync(CancellationToken cancellationToken)
{
    string connectionString = "{MyConnectionString}";
    await using EventHubConsumerClient consumer = new EventHubConsumerClient(EventHubConsumerClient.DefaultConsumerGroupName,connectionString,EventHubName);
    Console.WriteLine("Listening for messages on all partitions");

    try
    {
        await foreach (PartitionEvent partitionEvent in consumer.ReadEventsAsync(cancellationToken))
        {
            ...
        }
    }
    catch (TaskCanceledException)
    {
        ...
    }
}

这是我在Visual Studio中遇到的错误

foreach语句无法对类型为“ IAsyncEnumerable”的变量进行操作,因为“ IAsyncEnumerable”不包含“ GetEnumerator”的公共实例定义

是否可以重写此行以用于C#7?

一些细节:

  • Visual Studio Professional 2017
  • 库目标框架: .NET Core 2.1 .NET 4.7.2

解决方法

可以通过手动管理枚举来使用不带C#8的库。基本形式如下:

public static async Task Main(string[] args)
{
    var connection = "<< CONNECTION STRING >>" ;
    var hub = "<< EVENT HUB NAME >>";
    var producer = new EventHubProducerClient(connection,hub);
    var consumer = new EventHubConsumerClient(EventHubConsumerClient.DefaultConsumerGroupName,connection,hub);

    try
    {
        Console.WriteLine("Sending...");

        using (var batch = await producer.CreateBatchAsync())
        {
            for (var index = 0; index < 50; ++index)
            {
                batch.TryAdd(new EventData(Encoding.UTF8.GetBytes(index.ToString())));
            }

            await producer.SendAsync(batch);
        }

        Console.WriteLine("Reading...");

        var iterator = consumer.ReadEventsAsync(new ReadEventOptions { MaximumWaitTime = TimeSpan.FromMilliseconds(500) }).GetAsyncEnumerator();

        try
        {
            var consecutiveEmpties = 0;

            while (await iterator.MoveNextAsync())
            {
                var item = iterator.Current;

                if (item.Data != null)
                {
                    Console.WriteLine($"\tEvent: { Encoding.UTF8.GetString(item.Data.Body.ToArray()) }");
                    consecutiveEmpties = 0;
                }
                else if (++consecutiveEmpties > 5)
                {
                    break;
                }
            }
        }
        finally
        {
           await iterator.DisposeAsync();
        }

        Console.WriteLine("Done reading.");
    }
    finally
    {
        await producer.CloseAsync();
        await consumer.CloseAsync();
    }

    Console.ReadKey();
}

如果愿意,也可以通过使用最新的编译器包将C#8与Visual Studio 2017一起使用,如对this问题的回答中所述。

道歉;我们本来打算提供一个示例来进行演示,但尚未有机会实施它。可以在this GitHub问题中找到更多上下文。