c# - Keep UI responsive using Tasks, Handle AggregateException -


i have problem handling aggregateexception if winforms application starts task keep responsive while task performing.

the simplified case follows. suppose form has slow method, instance:

private double slowdivision(double a, double b) {     system.threading.thread.sleep(timespan.fromseconds(5));     if (b==0) throw new argumentexception("b");     return / b; } 

after pressing button want form show result of slowdivision(3,4). following code hang user interface time:

private void button1_click(object sender, eventargs e) {     this.label1.text = this.slowdivision(3, 4).tostring(); } 

hence i'd start task processing. when task finishes, should continue action display result. prevent invalidoperationexception need sure label1 accessed thread created on, hence control.invoke:

private void button1_click(object sender, eventargs e) {     task.factory.startnew ( () =>     {         return this.slowdivision(3, 4);     })     .continuewith( (t) =>     {         this.invoke( new methodinvoker(() =>          {             this.label1.text = t.result.tostring();         }));     }); } 

so far, good, how handle exceptions, instance if want calculate slowdivision(3, 0)?

normally if task throws unhandled exception, forwarded waiting thread via aggregateexception. numerous examples show following code:

var mytask = task.factory.startnew ( () => ...); try {     mytask.wait(); } catch (aggregateexception exc) {     // handle exception } 

the problem is: can't wait task execute, because want ui remain responsive.

create task continuation on faulted read task.exception , handle accordingly doesn't work:

private void button1_click(object sender, eventargs e) {     var slowdivtask = task.factory.startnew(() =>     {        return this.slowdivision(3, 0);     });      slowdivtask.continuewith((t) =>     {         this.invoke(new methodinvoker(() =>         {             this.label1.text = t.result.tostring();         }));     }, taskcontinuationoptions.notonfaulted);      slowdivtask.continuewith((t) =>     {         aggregateexception ae = t.exception;         ae.handle(exc =>         {             // handle exception             return true;         });     }, taskcontinuationoptions.onlyonfaulted); } 

a try / catch in function doesn't (as expected).

so how react on aggregateexceptions thrown task without waiting it.

if can use .net 4.5, use newer async/await, simplifies code lot, , saves having deal continuations , aggregateexceptions, create noise in code , distract focusing on trying accomplish.

it this:

private async void button1_click(object sender, eventargs e) {     try     {         double result = await task.run(() => this.slowdivision(3, 0));         this.label1.text = result.tostring();     }     catch (exception ex)     {         this.textbox1.text = ex.tostring();     } }  private double slowdivision(double a, double b) {     system.threading.thread.sleep(timespan.fromseconds(5));     if (b == 0) throw new argumentexception("b");     return / b; } 

Comments

Popular posts from this blog

How has firefox/gecko HTML+CSS rendering changed in version 38? -

javascript - Complex json ng-repeat -

jquery - Cloning of rows and columns from the old table into the new with colSpan and rowSpan -