2011-02-03 2 views
0

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

Где я не понимаю, как именно функционирует методология, я включил в нее вопросы.

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

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

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

ответ

1

Самой безопасной формой аннулирования всегда является сотрудничество.

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

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

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

BackgroundWorker будет работать отлично в ASP.NET, и это supports cooperative cancellation.

1

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

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

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