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) and this works fine (I don't belive this is the cause of my problem).
When I run this method from another class, Class Batch
, I do this via a "controller" method
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 belive - through testing) 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. The problem seems to be with passing the CancellationTokenSource
etc. to the child method. The IsCancellationPending
event fires and kills the controlling method, which causes the child method to hang.
Can anyone tell me what I am doing wrong or (more pertinently), what should I be doing to allow such a cancellation procedure?
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.