Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Async/Await Iterate over returned Task<IEnumerable<SomeClass>>

Tags:

c#

async-await

I want to use async/await when querying a database with a HTTP call in my WPF application. It's my first time using async/await, so if you see any obvious mistake, feel free to point them out.

The problem is, that im not able to iterate over the returned collecting anymore, because it's now a Task of <IEnumerable<SomeClass>>, and from what I found out, the Task doesn't implement IEnumerable/IEnumerator.

My code look like this: The method that calls the async/await method.

private void AddProjectDrawingAndComponentsFromServerToLocalDbAsync(CreateDbContext1 db, Project item)
{
   var drawings = client.GetDrawingsAsync(item.ProjectId);
   ..... (waiting for GetDrawingsAsync to return, so i can iterate over the drawings)
   db.SaveChanges();
}

The method GetDrawingsAsync:

public async Task<IEnumerable<Drawing>> GetDrawingsAsync(int projectId)
{
    var drawings = Task.Factory.StartNew(() => _client.Get(new GetDrawingsReq() { ProjectId = projectId }));
    return await drawings;
}

Back to the method that waits for the async method to finish:

private void AddProjectDrawingAndComponentsFromServerToLocalDbAsync(CreateDbContext1 db, Project item)
{
    var drawings = client.GetDrawingsAsync(item.ProjectId);  <-- The returned Task<Task<IEnumerable<Drawing>>
    Drawing prj_drawing = null;
    foreach (var draw in drawings)
    {
        prj_drawing = new Drawing() { DrawingKey = draw.DrawingKey, Name = draw.Name, ProjectId = item.ProjectId };
        item.AddDrawing(prj_drawing);
        db.Projects.Add(item);
    }
    db.SaveChanges();
}

How would I be able to convert the returned type Task<IEnumerable<Drawing>> to something that i can iterate over in the foreach loop.

like image 737
RooKie- Avatar asked Apr 30 '13 10:04

RooKie-


People also ask

What is task IEnumerable in C#?

Task<IEnumerable<T>> provides records once the data in collection is ready to send to the caller. Whereas, IAsyncEnumerable provides records as they are ready, which mean it will send you record as its available rather than waiting for the whole collection to be filled up.

What is async enumerable?

Async Streams or IAsyncEnumerable<T> provides a way to iterate over an IEnumerable collection asynchronously while using the yield operator to return data as it comes in.

Can I use await in ForEach c#?

There's no extension for serial execution; just do a foreach with an await in your loop body. @mare: ForEach only takes a synchronous delegate type, and there's no overload taking an asynchronous delegate type.

How do I use async and await in for loop?

You can use a for-of loop or a for/while loop, it doesn't really matter which one you pick. (async() => { data = [1, 2, 3, 4, 5]; for (let e of data) { const i = await somePromiseFn(e); console. log(i); } console.


1 Answers

To iterate over the result of the Task, you need to get the result of the Task. And to do that, you should use await. This means you should change AddProjectDrawingAndComponentsFromServerToLocalDbAsync() into an async method:

private async Task AddProjectDrawingAndComponentsFromServerToLocalDbAsync(
    CreateDbContext1 db, Project item)
{
    var drawings = await client.GetDrawingsAsync(item.ProjectId);
    foreach (var draw in drawings)
    {
        // whatever
    }
    db.SaveChanges();
}

This means that AddProjectDrawingAndComponentsFromServerToLocalDbAsync() (which is BTW quite a bad name for a method, I think) now returns a Task, so you should probably change the method that calls it into an async method too. This leads to “async all the way”, but that's unavoidable.

like image 153
svick Avatar answered Oct 25 '22 09:10

svick