Как прервать задачу .NET? - PullRequest
6 голосов
/ 14 августа 2011

Вот ситуация, я пишу основу для конкурса кодовой войны.Поскольку код выполняется, для каждого хода он вызывает метод в библиотеке, предоставленной каждым участником.По правилам конкурса метод должен вернуться через 1 секунду, иначе мы убьём задачу, вызвав их.Затем мы используем результат по умолчанию для этого хода.

Метод не поддерживает отмену, поскольку мы не можем доверять вызываемому коду в ответ на отмену.И нам нужно убить поток, потому что если у нас есть 10 или 20 пропущенных фоновых задач, то все вызовы, идущие вперед, будут обеспечивать меньше тактовых циклов при каждом вызове, а методы, которые раньше занимали менее 1 секунды, теперь занимают больше.

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

Обновление: Здесь необходимо иметь в виду две вещи.Во-первых, это как игра - так важна производительность.Во-вторых, рабочий поток вряд ли будет иметь какие-либо открытые ресурсы.Если один из вызванных методов идет слишком долго, мне нужно прервать его и быстро двигаться дальше.

Ответы [ 3 ]

2 голосов
/ 14 августа 2011

Вы должны запускать каждого участника в его собственном AppDomain с низкими привилегиями. Это имеет несколько преимуществ:

  1. Песочница
  2. Он не может взаимодействовать с любым другим кодом в процессе
  3. Принудительная выгрузка домена приложения относительно чистая.

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

К сожалению Thread.Abort недостаточно. Он по-прежнему выполняет предложения finally, которые могут занимать столько времени, сколько они хотят.

1 голос
/ 14 августа 2011

Thread.Interrupt () метод, возможно, то, что вы ищете.

Как сказано в документации MSDN: «Если этот поток в настоящее время не заблокирован в состоянии ожидания, сна или соединения, он будет прерван, когда в следующий раз начнет блокировать.»

Это не прерывание, оно заставляет работающий поток генерировать исключение ThreadInterruptedException, когда поток переходит в состояние ожидания.

Затем вы можете использовать таймер в другом потоке с таймаутом, чтобы проверить, действительно ли поток не хочет завершаться, если поток отказывается завершаться, например, через 30 секунд, вы можете прервать его.

1 голос
/ 14 августа 2011

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

Для связи вам, вероятно, следует избегать удаленного взаимодействия .NET, так как это, скорее всего, останется в несогласованном состоянии на стороне сервера. Некоторые другие варианты: сокеты, именованные каналы, веб-сервис.

...