TPL How to cancel a task correctly

I have the following task

cancelSource = new CancellationTokenSource(); token = cancelSource.Token; string strDbA = textBox1.Text; string strDbB = textBox2.Text; // Start duplication on seperate thread. asyncDupSqlProcs = new Task<bool>(state => UtilsDB.DuplicateSqlProcsFrom(token, mainForm.mainConnection, strDbA, strDbB), "Duplicating SQL Proceedures"); asyncDupSqlProcs.Start(); asyncDupSqlProcs.ContinueWith(task => { switch (task.Status) { // Handle any exceptions to prevent UnobservedTaskException. case TaskStatus.Faulted: // Error-handling logic... break; case TaskStatus.RanToCompletion: if (asyncDupSqlProcs.Result) Utils.InfoMsg(String.Format( "SQL stored procedures and functions successfully copied from '{0}' " + "to '{1}'", strDbA, strDbB)); break; case TaskStatus.Canceled: Utils.InfoMsg("Copy cancelled at users request."); break; } }, TaskScheduler.FromCurrentSynchronizationContext()); 

In the DuplicateSqlProcsFrom(token, mainForm.mainConnection, strDbA, strDbB) method DuplicateSqlProcsFrom(token, mainForm.mainConnection, strDbA, strDbB) I have a standard undo detection:

 if (_token.IsCancellationRequested) _token.ThrowIfCancellationRequested(); 

The cancellation event is a button click on the main form, inside the click event I have:

 try { cancelSource.Cancel(); asyncDupSqlProcs.Wait(); } catch (AggregateException aggEx) { if (aggEx.InnerException is OperationCanceledException) Utils.InfoMsg("Copy cancelled at users request."); } 

but I may seem to have caught an AggregateException , what am I doing wrong here?

Edit: inside the DuplicateSqlProcsFrom(token, mainForm.mainConnection, strDbA, strDbB) method DuplicateSqlProcsFrom(token, mainForm.mainConnection, strDbA, strDbB) I can catch OperationCancelledException , but I'm confused about how to handle it. The entire example that I saw handles the print "Operation Canceled ...", etc. In the user interface thread in the event that caused the cancellation. What is the best way to capture a cancel and pass it back to the user interface / calling thread?

+4
source share
2 answers

To get an OperationCancelledException , it must be thrown with the same token as the one passed to the task constructor:

 new Task<bool>(state => UtilsDB.DuplicateSqlProcsFrom(token, mainForm.mainConnection, strDbA, strDbB), "Duplicating SQL Proceedures", token); 
+1
source

Most likely, this is due to the Just My Code mode (the default for verification) in Visual Studio. The debugger breaks before the TPL can observe except. Try unchecking the box and see if it clears everything (Tools-> Options-> Debugging-> General, then uncheck)

+2
source

Source: https://habr.com/ru/post/1400454/


All Articles