.net - C# async await using LINQ ForEach() -
i have following code correctly uses async/await paradigm.
internal static async task addreferencsedata(configurationdbcontext context) { foreach (var sinkname in requiredsinktypelist) { var sinktype = new sinktype() { name = sinkname }; context.sinktypecollection.add(sinktype); await context.savechangesasync().configureawait(false); } }
what equivalent way write if, instead of using foreach(), want use linq foreach()? one, example, gives compile error.
internal static async task addreferencedata(configurationdbcontext context) { requiredsinktypelist.foreach( sinkname => { var sinktype = new sinktype() { name = sinkname }; context.sinktypecollection.add(sinktype); await context.savechangesasync().configureawait(false); }); }
the code got work without compile error this.
internal static void addreferencedata(configurationdbcontext context) { requiredsinktypelist.foreach( async sinkname => { var sinktype = new sinktype() { name = sinkname }; context.sinktypecollection.add(sinktype); await context.savechangesasync().configureawait(false); }); }
i'm worried method has no async signature, body does. correct equivalent of first block of code above?
no. isn't. foreach
doesn't support async-await
, requires lambda async void
should only used event handlers. using run async
operations concurrently , won't wait them complete.
you can use regular foreach
did if want extension method need special async
version.
you can create 1 iterates on items, executes async
operation , await
s it:
public async task foreachasync<t>(this ienumerable<t> enumerable, func<t, task> action) { foreach (var item in enumerable) { await action(item); } }
usage:
internal static async task addreferencsedata(configurationdbcontext context) { await requiredsinktypelist.foreachasync(async sinkname => { var sinktype = new sinktype() { name = sinkname }; context.sinktypecollection.add(sinktype); await context.savechangesasync().configureawait(false); }); }
a different (and more efficient) implementation of foreachasync
start async
operations , await
of them that's possible if actions can run concurrently isn't case (e.g. entity framework):
public task foreachasync<t>(this ienumerable<t> enumerable, func<t, task> action) { return task.whenall(enumerable.select(item => action(item))); }
as noted in comments don't want use savechangesasync
in foreach begin with. preparing changes , saving them @ once more efficient.
Comments
Post a Comment