Click here to Skip to main content
15,902,112 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
Hi all,

I'm trying to get several Task(Of IEnumerable(Of String)) – as the result of another LINQ query which is well populated – and try to get the String-Enumerables all into one single set of IEnumerable(Of String) using LINQ.

I guess it's best to post my sample code. I've tried several conversions (with and without Task.result etc.) for hours and feel clueless now.

Would someone please have a quick look and a suggestion?

Thank you,
Michael

What I have tried:

Try
   Dim entriesTasksQuery = From fi In LTODateilisten Select Task.Run(Function() GetRelevantLines(fi))

   Task.WaitAll(entriesTasksQuery)
   Dim totalEntries as IEnumerable(Of String) = Concatenate(Of String)(entriesTasksQuery)

   Return totalEntries

Catch ex As Exception
      MsgBox(ex.ToString(), MsgBoxStyle.Critical, My.Application.Info.Title)
      Return Nothing

End Try
The "Concatenate"-Function is a helper function I was able to find in another thread. I'm not very experienced, probably is there a better approach?
Public Shared Function Concatenate(Of T)(ParamArray ByVal lists() As IEnumerable(Of T)) As IEnumerable(Of T)
    Return lists.SelectMany(Function(x) x)
End Function
Posted
Updated 24-Jul-23 22:51pm

Dave is correct; if you add in the variable types, you can see the problem more easily:
VB.NET
Dim entriesTasksQuery As IEnumerable(Of Task(Of IEnumerable(Of String))) = ...
It's obvious that you can't pass the entriesTasksQuery variable to a function that expects an array of IEnumerable(Of String) values.

The simplest option is to skip your custom function and call SelectMany directly:
VB.NET
Dim totalEntries as IEnumerable(Of String) = entriesTasksQuery.SelectMany(Function(x) x.Result)

NB: You'll also need a ToArray to get the Task.WaitAll call to work:
VB.NET
Task.WaitAll(entriesTasksQuery.ToArray())
Without that, you'll get a BC30512 compiler error (Option Strict On disallows implicit conversions from 'IEnumerable(Of Task(Of IEnumerable(Of String)))' to 'Task'), or an InvalidCastException at runtime if you have Option Strict Off (definitely NOT recommended).
 
Share this answer
 
Comments
Sonhospa 25-Jul-23 5:09am    
EDIT: I'm sorry I had to walk back... was a bit too euphoric when the first breakpoint was reached. I've put in your suggestions and get a runtime error in the "Return totalEntries" line now. (German System, I hope that works for you):
Das Objekt des Typs "<selectmanyiterator>d__17`2[System.Threading.Tasks.Task`1[System.Collections.Generic.IEnumerable`1[System.String]],System.String]" kann nicht in Typ "System.Threading.Tasks.Task`1[System.Collections.Generic.IEnumerable`1[System.String]]" umgewandelt werden.

It's extremely confusing and overwhelming for me. As mentioned, I'm not very experienced.

EDIT: I've changed that last line to "Return Task.FromResult(totalEntries) and this seems to do it now! So again: THANK YOU VERY MUCH!
Richard Deeming 25-Jul-23 11:20am    
If you're returning a Task(Of IEnumerable(Of String)), then it would be simpler to use an Async method with Task.WhenAll:
Dim entriesTasksQuery As IEnumerable(Of Task(Of IEnumerable(Of String))) = From fi In LTODateilisten Select Task.Run(Function() GetRelevantLines(fi))
Dim values As IEnumerable(Of IEnumerable(Of String)) = Await Task.WhenAll(entriesTasksQuery)
Return values.SelectMany(Function(x) x)
You're trying to cast the Task objects into strings. You, obviously, can't do that.

You need the Result property of each Task, then you can concatenate those together.
 
Share this answer
 
Comments
Sonhospa 25-Jul-23 2:42am    
First: Good morning from the UK!

How would I get the result properties of all these tasks in LINQ and concatenate those together? Searching Google for hours and trying plenty of the suggested approaches (mostly given for different (syntax-) problems) was the reason why I gave up and "asked an expert" here in the first place.

Dim entriesTaskResults = entriesTasksQuery.Result leads to a compiler error:
"'result' is not a member of IEnumberable(Of Task(Of Ienumerable(Of String)))"
Dave Kreskowiak 25-Jul-23 9:22am    
You're not even looking at the tasks in the collection. You're thinking the collection of tasks should contain the Result property. You have to get the Result property of each task IN the collection. That means you have to iterate over the contents of the collection, get each task, then get the Result property of each task and concatenate them.

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900