c# - Multiple parallel awaitable tasks -


i'm experimenting ways improve performance in our asp.net applications. 1 of things i'm looking @ using parallelism , making operations async try reduce processing time , improve throughput. started mocking frequently, issue multiple database retrievals render page.

public actionresult index() {     var dal = new dal();     var cases = new list<case>();     cases.addrange( dal.getassignedcases() );     cases.addrange( dal.getnewcases() );     return view( "cases", cases ); } 

the 2 dal methods use thread.sleep(2000) simulate query , return collection of hard-coded objects. run apache bench using ab -c 1 -n 1 , takes 4 seconds. first attempt try improve was:

public actionresult index() {     var dal = new dal();     var assignedcases = task.factory.startnew( () => dal.getassignedcases() );     var newcases = task.factory.startnew( () => dal.getnewcases() );     ienumerable<case>[] allcases = task.whenall( assignedcases, newcases ).result;     return view( "cases", allcases.selectmany( c => c ) ); } 

when run using same ab command shows 2 seconds, makes sense because i'm running 2 tasks each of takes 2 seconds they're running in parallel.

when change benchmark 10 concurrent requests (i.e. ab -n 10 -c 10) following.

fulfilled  original parallel  50%         4014     2038  66%         4015     2039  75%         4017     4011 

the rest of numbers 100% similar in both columns.

i'm assuming i'm running here thread pool contention. 2/3 of requests fulfilled , after stuff sitting around waiting threads service requests. think maybe if added async mix more requests being served more quickly. that's start having problems , don't know if problem way i'm simulating long-running queries or way i'm using language feature or if i'm on wrong track , light @ end of tunnel on-coming train. :-)

first thing did create dalasync. in dalasync replaced thread.sleep(2000) await task.delay(2000), marked each method async keyword , changed return type ienumerable<case> task<ienumerable<case>>. wrote new controller method pieced information i've read in half-dozen blog posts , msdn articles.

public async task<actionresult> index() {     var dal = new dalasync();     var assignedcases = dal.getassignedcasesasync();     var newcases = dal.getnewcasesasync();     var allcases = await task.whenall( assignedcases, newcases );     return view( "cases", allcases.selectmany( c => c ) ); } 

when run using ab never finishes, 1 request ends timing out. tried following variation, works returns numbers identical original version (which sort of makes sense, because seems i'm serializing queries again).

var assignedcases = await dal.getassignedcasesasync(); var newcases = await dal.getnewcasesasync(); var allcases = new list<case>( assignedcases ); allcases.addrange( newcases ); 

what i'd have happen is:

  • run 2 queries in parallel
  • when controller waiting dal methods respond frees thread , lets other requests execute.

your first code sample should work, eyes appears bit strange. task.whenall introduced non-blocking operation, i.e. use await task.whenall(mytasks). using .result, turning blocking operation, not feel entirely natural used way.

i think after task.waitall(params task[]) designed blocking operation.

your second code sample however, looks near perfect , go for. implementing asynchronous code throughout code-base makes cleaner implementation.


Comments

Popular posts from this blog

How to mention the localhost in android -

php - Calling a template part from a post -

c# - String.format() DateTime With Arabic culture -