We are building an ASP.Net Core 3.1 application. It contains a page a list of work items and a form that allows some items to be assigned to someone. If the controller action succeeds, it ends with a redirect to the action which shows the work items once more.

It noticed that sometimes the list is reloaded with some items with the old assignment and a refresh then gets the updated list.

The controller GET action for the list is async, with an await for the code that gets the list of items, with some nested code to get data form the database with a Linq to Entities query with `ToListAsync()`.

```
public async Task<IActionResult> Index()
{
    _log.Debug("Getting work items");
    List<Item> model = await _itemData.GetItems();
    return View(model);
}

```

The controller POST action is also async, but without any await. 

```
public async Task<IActionResult> Index(int employeeId, int[] itemIds)
{
    _itemData.Assign(employeeId, itemIds);

    _log.Debug("Redirecting to work items");
    return RedirectToAction(nameof(Index));
}

```

However, code being called contains a construction like this:

```
public bool Assign(int employeeId, int[] itemIds)
{
    _log.Debug("Start assigning items");
    Array.ForEach(itemIds, async itemId =>
    {
        _log.Debug($"Done assigning item {itemId}");
        using (var scope = _serviceScopeFactory.CreateScope())
        {
            var db = scope.ServiceProvider.GetService<context>();

            Item item = await db.Items.Where(i => i.Id == itemId).FirstOrDefaultAsync();
            item .EmployeeId= employeeId;
            await db.SaveChangesAsync();
            _log.Debug($"Done assigning item {itemId}");
        }
    });

    _log.Debug("Done assigning items");
    return true;
}

```

*I have simplified the code quite a bit, and hope that I didn't introduce inconsistencies with that...*

I wonder how this actually works. 

The loop is processed with an `async` instruction. This code await `FirstOrDefaultAsync()` and `SaveChangesAsync()`, but only within the loop. The logging reveals that the method itself returns before all awaited tasks have completed.

**Log**

```
Getting work items
Start assigning items
Start assigning item 1234
Start assigning report 2345
Done assigning item
Redirecting to work items
Getting work items
Done assigning item 1234
Done assigning item 2345

```

Is this expected behaviour?

I tried to make the `Assign()` method async and await its call, but as I expected, this did not change the results.

Can I combine an async assignment and awaiting the complete result in a fail safe way, or would it be best to simply change to a completely synchronous solution?