2016-10-07 6 views
1

Резьба поддерживает прерывание. Почему не задание?C# Почему прерывание задачи не поддерживается?

С моей (несведущий) точки зрения, представляется целесообразным разрешить задачу, чтобы поддержать прерывание:

  • Если задача не в настоящее время выполняется на тему, называя task.Interrupt() установит TaskInterruptException которые будут выбрасываться, когда задание запланировано.
  • В противном случае исключение TaskInterrupException будет выбрано в потоке, выполняющем задачу, причем это исключение будет либо уловлено в задаче, либо добавлено в исключение AggregateException вверху. Я предполагаю, что эта функция потребует задания знать исполняемый поток (это неразумно?)

Нужны ли части, необходимые для реализации этой функции, или это потребует изменений в реализации языка?

Дополнение Я прочитал многочисленные вопросы на SO, которые обсуждают убийство/прерывание задачи, связанные с ними ответами обсуждающих CancellationToken и (обескуражено) Thread.Abort подходом.

В моем собственном возиться я обнаружил, что регистрация Thread.Interrupt с CancellationToken.Register не прерывает поток, выполняющийся в задаче, а вместо этого прерывает отмену потока на токене.

Таким образом, как я вижу, все же существует потребность в санкционированной функции, позволяющей разработчику гарантировать, что задача может быть (мягко) прекращена.

Я также добавить (чтобы кто-то сказал «переписывают свои задачи взять CancellationTokens»), что эта функция является особенно ценным в ситуациях, когда разработчик делает не собственный код выполняется в задачах.

И, по сути, кажется, что должен быть способ, которым исполнитель Задачи мог бы обеспечить гарантию отмены, а не в зависимости от того, что исполнитель Задачи сделал что-то правильно с помощью аннулирование токен.

Еще одно дополнение: Независимо от рисков, C# API поддерживает Thread.Abort и Thread.Interrupt. Поэтому мой вопрос, по сути, почему Task поддерживает тот же API (с теми же присущими рисками)?

Update
Это сообщение было помечено как дубликат this question. Тем не менее, я уже прочитал упомянутый вопрос до публикации этого (и всех ответов) - этот вопрос не является дубликатом, а связанным с ним вопросом, требующим дополнительной информации. Этот вопрос спрашивает: «Можете ли вы отменить», и ответы по существу «вы не должны прерывать» - мой вопрос спрашивает: «Учитывая, что прерывание лучше, чем прерывание, почему не прерывает поддерживаемую функцию? Какие механические препятствия запрещают эту функцию?». Согласно this question, существуют важные различия между прерыванием и , прерывая поток, и это прерывание является очень предпочтительным.

+3

http://stackoverflow.com/a/14831590/17034 –

+0

Благодарим вас за ссылку, Ханс. Там вы обсуждаете Thread.Abort. То же самое верно для Thread.Interrupt? Я понял, что Thread.Interrupt должен был избегать бросать исключения в неприятных местах. –

+0

Кроме того, независимо от рисков API по-прежнему поддерживает Thread.Abort и Thread.Interrupt. Мой вопрос в том, почему Task не поддерживает то же самое? –

ответ

1

И, по сути, кажется, что исполнитель Задачи должен иметь возможность гарантировать гарантию отмены, а не в зависимости от того, что исполнитель Задачи сделал что-то правильно с маркером отмены.

Я не согласен с этим утверждением. Любое затруднение имеет высокий риск оставить вашу систему в неопределенном состоянии, где она не может просто продолжать нормально функционировать, особенно если вы пытаетесь прервать задачи, которые у вас нет.

Так разработанное изящное отключение Задачи - единственный способ избежать таких ситуаций. Предпочитаете ли вы систему в производстве (которая рассчитана на запуск 24/7) для утечки ресурсов и непредвиденного сбоя или просто для удаления лишних ресурсов и времени, когда у вас нет возможности отменить Task, который не принимает CacnellationToken?

Это мое личное мнение, и я нахожу Task.Abort() довольно вредным, чем полезным в большинстве случаев.

EDIT: Кроме того, Task просто дескриптор операции, вы можете создать TaskCompletionSource<T> и установить завершение в любой момент времени на какой-либо теме, так что это не возможно, чтобы отследить нить (s) где логический код за этим Task действителен. Например, возвращает Task. Как бы вы это прекратили? Он не работает ни на одном потоке, а вместо этого прислушивается к выполнению заданий. То есть просто технически невозможно добавить общий метод Abort.

+0

Серж, я рад, что вы добавили редактирование - вот такая информация, которую я искал в этом вопросе. Повторить: «фактический код, поддерживающий задачу и дескриптор задачи, может не подключаться, что делает невозможным идентификацию через Задачу кода, который необходимо прервать». –

+0

Я понимаю, что код, предназначенный для работы 24/7, никогда не захочет прервать поток. Тем не менее, мой прецедент - это вычислительные конвейеры, работающие на основе оплаты в час. Если что-то пойдет не так, мы хотим как можно быстрее сбить все (так что пользователь не получает дополнительную плату), а также каталогизирует источники ошибок как можно точнее (поэтому мы можем исправить проблему в нашем конвейере). –

+0

Должно быть технически возможно принудительно прервать «Задачу», используя некоторые оболочки, «Thread.Abort()» и «Thread.ResetAbort()». Вы можете добавить еще один вопрос о том, как именно это сделать, потому что это самый дешевый способ решить проблему в вашем конкретном случае. –