.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
Post a Comment