Как я могу ограничить, как долго задача выполняется в .Net? - PullRequest
0 голосов
/ 03 февраля 2011

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

Когда мне неясно, как именно работает методология, я включил в нее вопросы.

Существующие методы, которые я знаю, хотя и не обязательно использовали сами:

  1. Создайте Thread, опросите его, чтобы он завершился в течение определенного времени, затем убейте поток. Это решение не очень хорошее, так как оно опирается на ThreadAbortException, что несколько неприятно, и, если я помню, у вас нет гарантии, где вы выйдете из кода, т. Е. Оно может оставить неиспользованные ресурсы в использовании и т. Д.
  2. Используйте шаблон IAsyncResult, проблема в том, что вы можете ждать определенное время, но не существует простого способа сообщить, что вы хотите, чтобы запрос был прерван, поэтому вы должны полагаться на настройку. логический флаг (или аналогичный), который проверяется внутри асинхронного кода и вызывает его остановку. Проблема здесь заключается в том, что если асинхронный код застрял в определенном разделе кода, он может продолжать работать в течение некоторого времени, прежде чем он фактически завершится.
  3. Я часто видел, как люди рекомендуют BackgroundWorker для асинхронных операций, но можете ли вы использовать это в ASP.Net (я бы так предположил), и есть ли у него простой способ завершить асинхронный процесс после определенного времени?
  4. Используйте Task API в .Net 4.0 (в настоящее время вся моя работа ограничена .Net 3.5, поэтому для меня это не вариант). Если вы быстро прочитаете документацию MSDN, то сможете легко отменить задачу, используя CancellationToken, но насколько быстро отменится действие отмены и обеспечит ли вызов любых блоков finally.

Все решения / предложения / методологии приветствуются

Ответы [ 2 ]

1 голос
/ 03 февраля 2011

Самая безопасная форма отмены - всегда кооперативная.

Я рекомендую никогда не убивать поток (через ThreadAbortException). Если у вас абсолютно нет выбора, сделайте этот код отдельным процессом , который можно просто убить. Домены приложений были хорошей идеей, но они не соответствуют реальному миру.

IAsyncResult, BackgroundWorker и CancellationToken - все это формы совместного отмены. Таким образом, все они очень чистые (не теряют ресурсы, вызывают блоки finally, ...), но имеют недостаток, заключающийся в том, что они не могут обрабатывать «мошеннический» код.

Если вы пишете код фоновой задачи, просто используйте BackgroundWorker или CancellationToken. Если вам нужно работать с, возможно, «мошенническим» кодом, оберните его в отдельный процесс.

BackgroundWorker будет отлично работать в ASP.NET, а поддерживает совместное аннулирование .

1 голос
/ 03 февраля 2011

Токен отмены от 4 и логический флаг от 2 - это один и тот же механизм. В обоих случаях задача должна регулярно взаимодействовать и проверять флаг. Преимущество 4 в том, что у вас есть стандартизированный флаг вместо того, чтобы создавать свой собственный.

Прерывание потоков - это зло, но управляемо, если ваш код написан тщательно. В частности, легко повредить глобальное состояние.

Безопасной версией прерывания потока является запуск его в другом домене приложения. Затем вы выгружаете домен приложений после того, как поток был убит. Это будет работать безопасным образом, если все ваши неуправляемые ресурсы имеют правильные критические финализаторы / используют SafeHandles.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...