У меня есть код, который использует Task.Run
с маркером отмены.Использование CancellationToken для Task.Run
Вот мой код:
public class TaskObject
{
CancellationTokenSource _source = new CancellationTokenSource();
public async Task TaskAction()
{
var task = Task.Run(async delegate
{
await TaskRun();
}, _source.Token);
//TaskCancel();
try
{
task.Wait();
}
catch (Exception ex)
{
}
}
public async Task TaskRun()
{
if (_source.IsCancellationRequested)
{
_source.Token.ThrowIfCancellationRequested();
}
SpeechSynthesizer _speechSynthesizer = new SpeechSynthesizer();
_speechSynthesizer.SpeakAsync("This is a test prompt");
}
public void TaskCancel()
{
_source.Cancel();
}
}
Если я называю TaskCancel()
в TaskAction()
, задача отменена исключение ловится.
Если я вызываю TaskCancel()
вне объекта, отмененное исключение не будет обнаружено.
Вот код, чтобы показать, где отменено исключение не перехвачено:
taskObject = new TaskObject();
await taskObject.TaskAction();
taskObject.TaskCancel();
Как я могу назвать TaskCancel()
снаружи объекта, так что отмененное исключение перехватывается?
Не обращайте внимания на SpeechSynthesizer, правильно ли я говорю, что при запуске Task.Run невозможно определить запрос отмены, если только в начале функции? – user3736648
@ user3736648, у вас появляется правильная идея, но формулировка нуждается в полировке (см. Первый абзац). Проще говоря, 'Task.Run' проверяет' CancellationToken' один раз, в самом начале, перед выполнением вашего делегата в пуле потоков. Когда вызов делегата выполняется, ничего не может сделать «Task.Run». –
Спасибо. Помимо Task.Run, существует ли правильный способ создания потока, который можно отменить в любое время? – user3736648