すべて、タスクパラレルライブラリ(TPL)を使用してバックグラウンドスレッド(キャンセルサポート付き)で実行する長時間実行プロセスがあります。この長時間実行されるタックのコードはClass Validation
、メソッド内に含まれています。
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()
、現在のプロセスがハングする原因となっているキャンセルです。CancellationTokenSource
問題は、子メソッドに渡すなどにあるようです。イベントが発生して制御メソッドが強制終了されIsCancellationPending
、子メソッドがハングします。
誰かが私が間違っていることを教えてもらえますか、または(より適切には)そのようなキャンセル手続きを許可するために私は何をすべきですか?
注:子タスクを生成して実行しようとしvalForm.AsyncRunValidationProcess(...)
ましCancellationToken
たが、これは機能しませんでした。
御時間ありがとうございます。