I have a method which loads some rows from a database, then performs an operation on every row.
Synchronously, it would look like this:
void DoSomething()
{
    using( IWebService web = new WebService( ... ) )
    using( IDatabaseService db = new DatabaseService( ... ) )
    {
        List<Entity> rows = db.GetRows( ... );
        foreach( Entity row in rows )
        {
            RelatedInfo info = web.GetRelatedInfo( row.Foo );
            web.MakeAnotherServiceCall( row.Bar );
            db.UpdateEntity( row.Id, info );
        }
    }
}
My async version looks like this (ConfigureAwait omitted for brevity):
async Task DoSomething()
{
    using( IWebService web = new WebService( ... ) )
    using( IDatabaseService db = new DatabaseService( ... ) )
    {
        List<Entity> rows = await db.GetRows( ... );
        List<Task> tasks = new List<Task>();
        foreach( Entity row in rows )
        {
            Entity localRow = row; // new alias to prevent capturing the foreach object in the closure
            Task task = new Task( async() =>
            {
                RelatedInfo info = await web.GetRelatedInfo( localRow.Foo );
                await web.MakeAnotherServiceCall( localRow.Bar );
                await db.UpdateEntity( localRow.Id, info );
            } );
            tasks.Add( task );
        }
        await Task.WhenAll( tasks );
    }
}
(For unrelated reasons I'm unable to test this right now, but I should be able to test it in a few days).
Notice how my per-row operation creates a new Task which is eventually awaited (inside Task.WhenAll).
Remember that I'm not wanting to start any background/pool threads (if I wanted that I would just use Task.Run). Instead I'm wanting all of these per-row work-items to run asynchronously on the same thread... but in my example above, do they?
The examples I've seen on StackOverflow so far, such as Asynchronous foreach - use the same pattern as me, except they use a separate class-level method (or they cop-out using Task.Run) - they don't use a lambda inside an explicit Task constructor:
async Task DoSomething()
{
    using( IWebService web = new WebService( ... ) )
    using( IDatabaseService db = new DatabaseService( ... ) )
    {
        List<Entity> rows = await db.GetRows( ... );
        List<Task> tasks = new List<Task>();
        foreach( Entity row in rows )
        {
            Task t = DoRow( row, web, db );
            tasks.Add( t );
        }
        Task.WhenAll( tasks );
    }
}
private static async Task DoRow(Entity row, IWebService web, IDatabaseService db)
{
    RelatedInfo info = await web.GetRelatedInfo( localRow.Foo );
    await web.MakeAnotherServiceCall( localRow.Bar );
    await db.UpdateEntity( localRow.Id, info );
}
My understanding so-far of Task and lambdas is that my lambda-based code should have the same asynchronous semantics as the separate-method code above - but I'm uncertain.
Update:
Perhaps a better way of phrasing my question is using continuations, which await abstracts away:
I understand this is what I'm wanting to achieve, but using the await keyword so I don't have to use ContinueWith manually, and without using Task.Run:
List<Task> tasks = new List<Task>();
foreach( Entity row in rows )
{
    Entity localRow = row;
    Task t = web
        .GetRelatedInfo( localRow.Foo )
        .ContinueWith( t1 => new { RelatedInfo = t1.Result, WebCall2 = web.MakeAnotherServiceCall( localRow.Bar ) } )
        .ContinueWith( t2 => db.UpdateEntity( localRow.Id, t2.RelatedInfo ) );
    tasks.Add( t );
}
Task.WhenAll( tasks );
 
     
    