Как я могу установить свой собственный тайм-аут?

StackOverflow https://stackoverflow.com/questions/533332

  •  22-08-2019
  •  | 
  •  

Вопрос

Мне приходится использовать API для вызова третьей стороны и в идеале использовать возвращаемый ею ответ.API имеет встроенный 30-секундный тайм-аут и не позволяет установить его программно.Мне нужно, чтобы время ожидания истекло через 12 секунд.Вот звонок, который я делаю:

строковый ответ = theAPI.FunctionA(a, b, c, d);

Я подумал, что для этого мне, возможно, придется использовать асинхронные вызовы и прервать поток через 12 секунд.Другой вопрос о stackoverflow, похоже, близок к тому, что я рассматриваю: Реализация общего тайм-аута C#

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

Это было полезно?

Решение

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

Другие советы

Thread.Abort конечно, закроет тему, так как вызовет Win32 TerminateThread.

Результат этого действия будет зависеть от того, насколько ваш API любит, когда его закрывают TerminateThread.

Если ваш метод называется что-то вроде NuclearPlant.MoveRod() или Defibrillator.Shock(), я лучше подожду эти 30 секунд.

Этот метод не дает жертве возможности выполнить какую-либо очистку:

TerminateThread используется для завершения потока.Когда это происходит, целевой поток не имеет возможности выполнить какой-либо код пользовательского режима.Библиотеки DLL, прикрепленные к потоку, не уведомляются о завершении потока.Система освобождает начальный стек потока.

Как сказано в MSDN:

TerminateThread — опасная функция, которую следует использовать только в самых крайних случаях.Вам следует позвонить TerminateThread только если вы точно знаете, что делает целевой поток, и контролируете весь код, который целевой поток может выполнять в момент завершения.Например, TerminateThread может привести к следующим проблемам:

  • Если целевой поток владеет критическим разделом, этот критический раздел не будет освобожден.
  • Если целевой поток выделяет память из кучи, блокировка кучи не будет снята.
  • Если целевой поток выполняет определенные вызовы kernel32, когда он завершается, состояние kernel32 для процесса потока может быть противоречивым.
  • Если целевой поток манипулирует глобальным состоянием общей DLL, состояние DLL может быть уничтожено, что повлияет на других пользователей DLL.
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top