.net - C# Task Return output -
i've read lot on how return value task can't seem work on code , still produces system.threading.threadabortexception
.
tried using task.waitall
though might block ui no avail.
public datatable getresult(somevariable somevariable) { // not work //var task = task<datatable>.factory.startnew(() => var task = task.factory.startnew<datatable>(() => { datatable matcheddata = new datatable(); matcheddata = dotask(somevariable); return matcheddata; }, taskcreationoptions.longrunning); try { var alltasks = new task[] { task }; task.waitall(alltasks); return task.result datatable; } catch (argumentexception) { throw; } catch (exception) { // exception here: "a first chance exception of type 'system.threading.threadabortexception' occurred in mscorlib.dll" throw; } }
tried using continuewhenall
still same.
public datatable getresultv2(somevariable somevariable) { queue = new queue<task>(); datatable matcheddata = new datatable(); var task = task.factory.startnew(() => { matcheddata = dotask(somevariable); return matcheddata; }, taskcreationoptions.longrunning); queue.enqueue(task); try { var done = task.factory.continuewhenall(queue.toarray(), completed => { return matcheddata; }); return done.result datatable; } catch (argumentexception) { throw; } catch (exception) { // exception here: "a first chance exception of type 'system.threading.threadabortexception' occurred in mscorlib.dll" throw; } }
the dotask
method checks , query databases.
private datatable dotask(somevariable somevariable) { datatable matcheddata = new datatable(); // long database process/query // populate , return matcheddata return matcheddata; }
edit: reference on how/why it's being used.
foreach (datarow row in data.rows) { string columnname = convert.tostring(row["columnname"]); string projectname = convert.tostring(row["projectname"]); string dbase_group = convert.tostring(row["dbase_group"]); string dbase_data = convert.tostring(row["dbase_data"]); var task = task.factory.startnew(() => { somevariable somevariable = new somevariable(); somevariable.dbname = dbase_group; somevariable.columnname = columnname; somevariable.projectname = projectname; somevariable.tblname = dbase_data; using (searchproject search = new searchproject()) { datatable result = new datatable(); result = search.getresult(somevariable); } }); queue.enqueue(task); } task.factory.continuewhenall(queue.toarray(), ant => { console.writeline("done tasks"); });
i think time take step async/await. make live easier.
somewhere in code want start several tasks , wait tasks complete without blocking user interface. in example getresult.
you want getresult return object of datatable. if want use async await, declare function getresult , return task, this:
public async task<datatable> getresultasync(somevariable somevariable) {...}
it quite common name async functions word async @ end
in function can start tasks, other things while these tasks running , wait tasks finish. waiting called "await".
you can await task or task object, await function returns task.
task.waitall doesn't return task, void. can't await task.waitall.
better await task.whenall. function returns task, , can await it.
public async task<datatable> getresultasync(somevariable somevariable) { var task = task.run( () => { datatable matcheddata = new datatable(); matcheddata = dotask(somevariable); return matcheddata; } }
if want can still use task.factory.startnew, see msdn discussions why nowadays prefer task.run
this function 1 result. if want call if, you'll have make caller function async , let return task or task. caller should async etc. until event handler. 1 may return void:
private async void onbutton1_clicke(object sender, ...) { try { await processallinputsasync(...) } catch (argumentexception exc) { processargumentexception(...) } catch (exception exc) { processotherexception(...) } } // first example: no parallel processing: private async task processallinputsasync(...) { foreach (somevariable somevariable in getsomevariables(...)) { datatable datatable = await getresultasync(...); processdatatable(datatable); } } // or parallel processing: start several tasks , wait until ready: private async task processallinputsasync(...) { list<task<datatable>> tasks = new list<task<datatable>>(); foreach (somevariable somevariable in getsomevariables(...)) { tasks.add(getresultasync(somevariable); } // tasks started, await finish: await task.whenall(tasks.toarray()); // remember: can await task or task<t> // task.whenall returns task, can await // task.waitall returns void, can't await it. // tasks finished, results: // each task<tresult> has result in property task.result // result of task<tresult> tresult: ienumerable<tresult> fetcheddatatables = tasks.select(task => task.result); // can process here if want or other things it: foreach (datatabe fetcheddatatable in fetcheddatatables) { processfetcheddatatable(fetcheddatatable); } }
see got rid of continuewith etc stuff. replace await, followed next statement result of task available in task.result.
be aware: if task.whenall, , 1 of tasks waiting throws exception, aggregateexception exceptions thrown tasks grouped in property innerexceptions. if want can catch aggregateexception , foreach innerexceptions see task threw exceptions.
Comments
Post a Comment