Все, у меня есть длительный процесс, который я запускаю в фоновом потоке (с поддержкой отмены), используя панель задач Paralell Library (TPL). Код для этого долго работает TAKS содержится в Class Validation
, и когда методMulti-Threading Cross-Class Cancellation with TPL
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;
}
}
запускается из Class Validation
я могу отменить процесс штраф. Запрос аннулирования обрабатывается соответствующим delegate
(см. Ниже), и это работает отлично (я не верю, что это причина моей проблемы).
Когда я запускаю этот метод из другого класса, Class Batch
, я делаю это через «контроллер» метод
asyncTask = Task.Factory.StartNew<bool>(() => asyncControlMethod(), token);
, который в свою очередь, вызывается метод
valForm.AsyncRunValidationProcess(uiScheduler, token,
new List<string>() { strCurrentSiteRelPath }));
где valForm
это мой аксессор к Class Validation
, метод работает нормально, но при попытке отмены delegate
cancelHandler = delegate
{
UtilsTPL.CancelRunningProcess(asyncTask, cancelSource);
};
где
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);
}
}
замерзает/зависания (без необработанного исключения и т.д.) на _task.Wait()
. Это (я верю - через тестирование) связано с тем, что я отменяю asyncControlMethod()
, который вызвал valForm.AsyncRunValidationProcess(...)
, поэтому он отменяет asyncControlMethod()
, что приводит к зависанию текущего процесса. Проблема заключается в передаче методу child CancellationTokenSource
и т. Д. Событие IsCancellationPending
срабатывает и уничтожает метод управления, который заставляет дочерний метод зависать.
Может ли кто-нибудь сказать мне, что я делаю неправильно или (более уместно), что я должен делать, чтобы разрешить такую процедуру отмены?
Примечание: Я пытался породить ребенка задачу для запуска valForm.AsyncRunValidationProcess(...)
, со своим собственным CancellationToken
, но это не сработало.
Спасибо за ваше время.
Как вы начинаете «Задачу»? Почему ваш метод принимает «TaskScheduler», когда он, похоже, не использует его? – svick
Он его использует. Прошедший «TaskScheduler» предназначен для потока пользовательского интерфейса. Я просто не показывал, что он используется, поскольку есть много кода.Он используется для обновления 'DataGridView' и общих элементов управления графическим интерфейсом (индикатор выполнения и т. Д.). – MoonKnight
И как вы начинаете «Задачу»? – svick