I had a method SplitInto2DArray that turned a File objects representing a CSV file into a File2DArray class.
File2DArray is a simple class that contains an array for Headers and a 2D array for the body.
public class File2DArray
{
public string[] Headers;
public string[][] Content;
}
To turn an array of File objects into File2DArray objects I did:
Files.Select(File => File.SplitInto2DArray().Content
However I made SplitInto2DArray into an async function as it was blocking the thread with numerous large CSV files.
When I did this I had to change the Select
function but I ran into a problem.
.Select(async File => await File.SplitInto2DArray().Content
SplitInto2DArray
no longer returns a File2DArray
but a Task<File2DArray>
which doesn't have the property Content
.
I could turn it into a multiline lambda but I am interested if there is a way of accessing the output of an await Task<T>
on the same line as the await.
CodePudding user response:
Try Files.Select(async File => (await File.SplitInto2DArray()).Content)
There is a pair of parentheses containing await File.SplitInto2DArray()
.
While the await
keyword blocks the current thread until the async function finish and return, the Task<File2DArray>
becomes File2DArray
.
Maybe it's not an accurate explanation but it should work.
CodePudding user response:
You can use System.Linq.Async nuget package to get nice extensions for IAsyncEnumerable
PM> Install-Package System.Linq.Async
And your code will look like
var contents = await Files.ToAsyncEnumerable()
.SelectAwait(async file => await file.SplitInto2DArray())
.Select(array => array.Content)
.ToListAsync();