List<T>.ForEach converts your async lambda into async void, as it accepts an Action<T>. Although it does that and that has some complications with exception handling, your ForEach call should work properly. If not, you might not be using the async pattern correctly. I would advise you to set a breakpoint after the first await and see the continuation executing.
I would advise you to use a regular foreach instead:
private async Task ProcessAllItemsAsync(List<Item> items) { foreach (var item in items) { var response = await Processor.IOBoundTaskAsync(item); // Some further processing on the response object. } } Read How can I use Async with ForEach?How can I use Async with ForEach? for more.