dotnet / vblang

The home for design of the Visual Basic .NET programming language and runtime library.
289 stars 65 forks source link

IAsyncEnumerable support #163

Open AnthonyDGreen opened 7 years ago

AnthonyDGreen commented 7 years ago

It's still a bit early to talk about this in detail but putting this placeholder out there for visibility.

There are several orthogonal features we could do for IAsyncEnumerable support.

Production

' Or like this? Dim q = Await item In asyncSource Where P(item) Select item.M, item.N

Nukepayload2 commented 4 years ago

Any updates? I can't use System.Threading.Channels.ChannelReader(Of T).ReadAllAsync because VB 16.0 doesn't support Await Each.

hez2010 commented 4 years ago

Any updates? I can't use System.Threading.Channels.ChannelReader(Of T).ReadAllAsync because VB 16.0 doesn't support Await Each.

Although you cannot use Await Each, you can use:

Dim a = ....ReadAllAsync()
Do
    Dim item = Await a.MoveNextAsync
    ...
Loop
Nukepayload2 commented 4 years ago

@hez2010 Your code didn't dispose the async enumerator. I don't know how to dispose the enumerator without rethrowing exceptions. Because Await is not allowed in Finally block.

<Extension>
Async Function AwaitEachAsync(Of TItem)(
    asyncEnumerable As IAsyncEnumerable(Of TItem),
    bodySync As Action(Of TItem)) As Task

    Dim readerEnumerator = asyncEnumerable.GetAsyncEnumerator
    Try
        Do While Await readerEnumerator.MoveNextAsync
            Dim item = readerEnumerator.Current
            ' The Await Each body
            bodySync(item)
        Loop
    Finally
        ' BC36943: 'Await' cannot be used inside a 'Catch' statement, a 'Finally' statement, or a 'SyncLock' statement.
        Await readerEnumerator.DisposeAsync
    End Try
End Function

<Extension>
Async Function AwaitEachAsync(Of TItem)(
    asyncEnumerable As IAsyncEnumerable(Of TItem),
    bodyAsync As Func(Of TItem, Task)) As Task

    Dim readerEnumerator = asyncEnumerable.GetAsyncEnumerator
    Try
        Do While Await readerEnumerator.MoveNextAsync
            Dim item = readerEnumerator.Current
            ' The Await Each body
            Await bodyAsync(item)
        Loop
    Finally
        ' BC36943: 'Await' cannot be used inside a 'Catch' statement, a 'Finally' statement, or a 'SyncLock' statement.
        Await readerEnumerator.DisposeAsync
    End Try
End Function