1

.NET 6 introduced the Parallel.ForEachAsync method which works pretty well in C#, but I'm running into issues using it in VB.NET.

Namely, the following example in C#:

using HttpClient client = new()
{
    BaseAddress = new Uri("https://api.github.com"),
};
client.DefaultRequestHeaders.UserAgent.Add(new ProductInfoHeaderValue("DotNet", "6"));
 
ParallelOptions parallelOptions = new()
{
    MaxDegreeOfParallelism = 3
};
 
await Parallel.ForEachAsync(userHandlers, parallelOptions, async (uri, token) =>
{
    var user = await client.GetFromJsonAsync<GitHubUser>(uri, token);
 
    Console.WriteLine($"Name: {user.Name}\nBio: {user.Bio}\n");
});

I cannot work out how to convert this section into VB.NET:

await Parallel.ForEachAsync(userHandlers, parallelOptions, async (uri, token) =>
    {
});

The most logical conversion I can think of is this:

Await Parallel.ForEachAsync(userHandlers, parallelOptions, Function(uri, token)
                                                           //stuff
                                                           End Function))

But that does not work, throwing an error BC36532: Nested function does not have a signature that is compatible with delegate 'Func(Of String, cancellationToken, ValueTask)'

I can appreciate that the method expects a ValueTask but I can't work out how to properly do that. Using a Sub instead of Function doesn't work either, neither does wrapping it all in a Task. There has to be something really dumb that I'm missing.

Any help would be greatly appreciated!

1
  • Is the use of Parallel.ForEachAsync() necessary? Can't you await Task.WhenAll() instead? -- I don't think the Sub() / Function() Lambda has been updated to support an awaitable ValueTask. You could return a ValueTask, removing async from the Lambda and unwrapping the Task manually. Commented May 28, 2022 at 8:58

2 Answers 2

1

Alright, so it was a Visual Studio glitch that persisted between restarts...

I did the following:

Await Parallel.ForEachAsync(Of String)(userHandlers, parallelOptions, New Func(Of String, CancellationToken, ValueTask) _
            (Function(uri, token)

Which worked, and then I removed the explicit stuff to get back to this:

 Await Parallel.ForEachAsync(userHandlers, parallelOptions, Function(uri, token)

Which is the exact function that didn't want to work before. Trying to make that nested function Async breaks it again with the same BC36532 error, but not as "permanently" as before. Very weird.

It would seem that maybe VB.NET just doesn't have support for nested Async?

Sign up to request clarification or add additional context in comments.

1 Comment

You might find this interesting.
-1

You aren't returning anything, so you need to use Sub instead of Function. VB.Net also has async anonymous methods similar to C#, but you must use the keywoard Async in front of it. Try this

Await Parallel.ForEachAsync(
    userHandlers, 
    parallelOptions, 
    Async Sub(uri, token)
        //stuff
    End Sub))

For more, see async modifier

3 Comments

I don't think that that will work because Sub will generate an Action delegate while ForEachAsync requires a Func.
I've been doing some testing and I can't find a combination that works.
Sub doesn’t work, unfortunately. I’m pretty good with using Async/Await, it’s just a struggle with this lambda expression in particular.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.