.net - Reduce Task Parallel Library "Boilerplate" -


my team using task parallel library first time, , colleague has come code listed below. running few things, using data make further server requests (the methods async in name), , using data comes server call more data. after of these loaded, items on ui (usually combo boxes) updated (in methods returned in name), user use filters.

basically, figure out companies user has access to, based on information, load more "filters" data (loading defaults), , load data default view.

while code works, seems there's lot of duplicate code, , wondering if extension method or other code change used reduce amount of code needed this.

private sub getandloadviewdata()     dim nocanceltoken = cancellationtoken.none     const attachtoparent taskcontinuationoptions = taskcontinuationoptions.attachedtoparent      task.factory.startnew(         sub()             'fire off child tasks              task.factory.startnew(function() getcompaniesasync()).continuewith(                 sub(t task(of list(of company))) companiesreturned(t), nocanceltoken, attachtoparent, uisynccontext)              task.factory.startnew(function() getuserasync()).continuewith(                 sub(t task(of user)) userreturned(t), nocanceltoken, attachtoparent, uisynccontext)         end sub).continuewith(             sub(prevtask)                 'these tasks depend on success of previous task                 if not prevtask.isfaulted                     task.factory.startnew(function() getfiltersasync()).continuewith(                         sub(t task(of list(of filter))) filtersreturned(t), nocanceltoken, attachtoparent, uisynccontext)                 else                     'rethrow exception previous task if exception occurred                     throw prevtask.exception                 end if             end sub).continuewith(                 sub(prevtask)                     'these tasks depend on success of previous task                     if not prevtask.isfaulted                         task.factory.startnew(function() getdataasync(currentcompany, currentfilters)).continuewith(                             sub(t task(of list(of data))) datareturned(t), nocanceltoken, attachtoparent, uisynccontext)                      else                         'rethrow exception previous task if exception occurred                         throw prevtask.exception                     end if                 end sub).continuewith(                     sub(prevtask)                         if prevtask.isfaulted                             view.handlefatalexception(prevtask.exception.innerexceptions.first())                         else                             view.displaydata()                         end if                     end sub, uisynccontext) end sub 

i note can use .net framework 4.0, due business reasons.

let me know if more information required.

i built rackspace threading library purpose (open source, apache 2.0 license).

another option using microsoft async package, allowing use async/await in .net 4.0 codebases.


it's bit challenging me read code in post. i've made few assumptions, in particular of methods end async return task or task<t> (in accordance task-based asynchronous pattern (tap) guidelines).

here's result might threading library mentioned, in c# syntax. then , select methods behave regular sequential code - of remaining ones cancelled exception thrown in one. finally extension method executes regardless of final state of antecedent (including cancelled). then method executes delegate returns task, , waits task complete (similar unwrap or use of attachedtoparent). select method executes synchronous block of code may or may not return value.

task[] initialtasks = {     getcompaniesasync().select(task => companiesreturned(task)),     getuserasync().select(task => userreturned(task)) }  taskex.whenall(initialtasks)     .then(_ => getfiltersasync().select(task => filtersreturned(task)))     .then(_ => getdataasync(currentcompany, currentfilters).select(task => datareturned(task)))     .select(_ => view.displaydata())     .finally(         task =>         {             if (task.isfaulted)                 view.handlefatalexception(task.exception.innerexceptions.first());         }); 

the taskex.whenall method not part of library, can implement follows:

public static task<task[]> whenall(params task[] tasks) {     return task.factory.continuewhenall(tasks, completed => completed); } 

also note in c#, various expressions of form task => fooreturned(task) replaced fooreturned, chose leave longer form it's clear readers fooreturned 1 of methods you're calling.


Comments

Popular posts from this blog

php - render data via PDO::FETCH_FUNC vs loop -

c++ - OpenCV Error: Assertion failed <scn == 3 ::scn == 4> in unknown function, -

The canvas has been tainted by cross-origin data in chrome only -