简体   繁体   中英

Check sent S2C messages with EventHubConsumerClient using .NET C# 7 and VS 2017

I'm starting with IoT Hub and Azure services. I'm following this quickstart tutorial: Quickstart: Send telemetry from a device to an IoT hub and read it with a back-end application (.NET)

I created a Free Tier IoT Hub in my Azure account and registered a device using Azure Cloud Shell. Now I'm developing a "starter" library send D2C messages and I can see that it is possible to read sent messages . I have problems with the last step, it seems that the code is written in C# 8, but I'm developing with VS 2017 and get an error in a await foreach loop.

The sample code is here , and this is the code I want to change to 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)
    {
        ...
    }
}

This is the error I get in Visual Studio:

foreach statement cannot operate on variables of type 'IAsyncEnumerable' because 'IAsyncEnumerable' does not contain a public instance definition for 'GetEnumerator'

Is it possible to rewrite this line to use with C# 7?

Some details:

  • Visual Studio Professional 2017
  • Library target framework: .NET Core 2.1 .NET 4.7.2

It is possible to use the library without C# 8 by managing the enumerable manually. The basic form would look something like:

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();
}

If you prefer, it is also possible to use C# 8 with Visual Studio 2017 by using the latest compilers package, as mentioned in the answer to this question.

Apologies; we've been intending a sample to demonstrate but have not yet had the opportunity to implement it. More context can be found in this GitHub issue.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM