c# - Many awaits for Async method, or a single await for a wrapping Task.Run? -
suppose have write down on database list of 1000 elements, through async flow. better await 1000 times asynchronous insert statement, or wrap 1000 inserts in 1 single synchronous method encapsulated task.run
statement, awaiting 1 single time?
for example, sqlcommand
has every method coupled async
version. in case, have insert statement, can call executenonquery
or executenonqueryasync
.
often, on async/await guidelines, read if have asynchronous version available method, should use it. suppose write:
async task save(ienumerable<savable> savables) { foreach(var savable in savables) { //create sqlcommand somehow var sqlcmd = createsqlcommand(savable); //use asynchronous version await sqlcmd.executenonqueryasync(); } }
this code clear. however, every time goes out await part, returns on ui thread, , in background thread in next await encountered, , on (doesn't it?). implies user can see lag, since ui thread continously interrupted continuation of await
execute next foreach
cycle, , in fraction of time ui freezes bit.
i want know if better write code this:
async task save(ienumerable<savable> savables) { await task.run(() => { foreach(var savable in savables) { //create sqlcommand somehow var sqlcmd = createsqlcommand(savable); //use synchronous version sqlcmd.executenonquery(); } }); }
in way, whole foreach
executed on secondary thread, without continuous switch between ui thread , secondary one. implies ui thread free update view entire duration of foreach
(for example spinner or progress bar), is, no lag perceived user.
am right? or missing "async way down"?
i'm not looking simple opinion-based answers, i'm looking explanation of async/await guidelines in case , best way resolve it.
edit:
i've read this question not same. question choice of single await
on async method versus single task.run
await. question consequences of calling 1000 await
, resources' overhead due continuous switching among threads.
your analysis largely correct. seem overestimate burden place on ui thread; actual work asked small, odds able keep fine, it's possible you'd doing enough couldn't, you're right interested in not performing continuations on ui thread.
what you're missing of course preferred way of avoiding of call backs ui thread. when await
operation, if don't need rest of method return original context can add configureawait(false)
end of task you're awaiting. prevent continuation running in current context (which ui thread) , instead let continuation run in thread pool thread.
using configureawait(false)
allows avoid ui being responsible non-ui work unnecessarily while preventing needing schedule thread pool threads more work need do.
of course, if work end doing after continuation going ui work, method shouldn't using configureawait(false);
, because wants schedule continuation on ui thread.
Comments
Post a Comment