Multi-Threading Cross-Class Cancellation with TPL
-
Monday, May 14, 2012 2:13 PM
All, I have a long running process that I run on a background thread (with cancellation support) using the Task Paralell Library (TPL). The code for this long running taks is contained within `Class Validation`, and when the method
public bool AsyncRunValidationProcess(TaskScheduler _uiScheduler, CancellationToken _token, dynamic _dynamic = null) { try { // Note: _uiScheduler is used to update the UI thread with progress infor etc. for (int i = 0; i < someLargeLoopNumber; i++) { // Cancellation requested from UI Thread. if (_token.IsCancellationRequested) _token.ThrowIfCancellationRequested(); } return true; } catch (Exception eX) { // Do stuff. Display `eX` if cancellation requested. return false; } }is run from `Class Validation` I can cancel the process fine. The cancellation request is handled by the appropriate `delegate` (shown below). However, when I run this method from another class via another method `asyncControlMethod()`, the cancellation stops working. The controller is invoked via
asyncTask = Task.Factory.StartNew<bool>(() => asyncControlMethod(), token);
which in turn invokes the method
valForm.AsyncRunValidationProcess(uiScheduler, token, new List<string>() { strCurrentSiteRelPath }));where `valForm` is my accessor to `Class Validation`, the method runs fine, but when I attempt a cancellation the `delegate`
cancelHandler = delegate { UtilsTPL.CancelRunningProcess(asyncTask, cancelSource); };where
public static void CancelRunningProcess(Task _task, CancellationTokenSource _cancelSource) { try { _cancelSource.Cancel(); _task.Wait(); // On cross-class call it freezes here. } catch (AggregateException aggEx) { if (aggEx.InnerException is OperationCanceledException) Utils.InfoMsg("Operation cancelled at users request."); if (aggEx.InnerException is SqlException) Utils.ErrMsg(aggEx.Message); } }freezes/hangs (with no unhandled exception etc.) on `_task.Wait()`. This I think is to do with the fact that I am cancelling `asyncControlMethod()` which has called `valForm.AsyncRunValidationProcess(...)`, so it is cancelling `asyncControlMethod()` which is causing the current process to hang.
**I know I am probably being stupid here, but can anyone tell me what I am doing wrong or should be doing to allow such a cancellation proceedure?**
_Note: I have tried to spawn a child task to run `valForm.AsyncRunValidationProcess(...)`, with its own `CancellationToken` but this has not worked._
Thanks for your time.
"Everything should be made as simple as possible, but not simpler" - Einstein
- Edited by Camuvingian Monday, May 14, 2012 2:27 PM
- Moved by Mike Dos ZhangMicrosoft Contingent Staff, Moderator Tuesday, May 15, 2012 7:14 AM Parallel (From:Visual C# General)
All Replies
-
Monday, May 14, 2012 2:34 PMAs I read the code I was asking myself why would one need to run one Asynchronous task within the other? But then I was wondering if the problem is with the cancelation token itself? Stehpen Toub discusses the association of the token when passing in with the task start, in this post. http://social.msdn.microsoft.com/Forums/en/parallelextensions/thread/c2f614f6-c96c-4821-84cc-050b21aaee45
JP Cowboy Coders Unite!
-
Monday, May 14, 2012 2:47 PM
I am looping through an Array of mathods using a generic method `TaskSpin` to reel off methods like `private bool ThisTask1() { ... }`, `private bool ThisTask2() { ... }`, etc. It just so happens that this task is discribed in another class, so to keep the consistancy of my loop and the ascociated `TaskSpin` method, I invoke the required method (the one in the other class, via a method `ThisTaskX() { ...} `. It may be that I will have to treat this method as exceptional an write a seperate piece of code to invoke it. But there must be a way to do what I want using child tasks or some other such magic?
"Everything should be made as simple as possible, but not simpler" - Einstein
-
Tuesday, May 15, 2012 7:15 AMModeratorPlease use this Parallel forum: http://social.msdn.microsoft.com/Forums/en-US/parallelextensions
Mike Zhang[MSFT]
MSDN Community Support | Feedback to us
-
Tuesday, May 15, 2012 1:26 PM
Mike, just move this thread thanks!
JP Cowboy Coders Unite!
-
Wednesday, May 16, 2012 1:24 AMModerator
-
Thursday, May 24, 2012 6:39 AM
I think there's no problem with the cancellation. The problem is that you call Task.Wait() on UI thread in CancelRunningProcess. That's the source of freezing your form.
Stephen Toub has explained it in this blog post:
http://blogs.msdn.com/b/pfxteam/archive/2011/01/13/10115163.aspx
-
Thursday, May 24, 2012 4:54 PM
This was the answer http://stackoverflow.com/a/10651160/626442. I was aware abotu the Wait() I was using it for testing. Sorry for the inconvienence. Thanks you very mucg for your time.
"Everything should be made as simple as possible, but not simpler" - Einstein
- Proposed As Answer by Stephen Toub - MSFTMicrosoft Employee, Owner Friday, August 24, 2012 6:08 AM
- Marked As Answer by Camuvingian Friday, August 24, 2012 9:35 AM

