Как Вы обрабатываете поток, который имеет подвешенный вызов?

Если у вас есть долгоживущая маленькая подстрока короткой, большой родительской строки, большой символ [], поддерживающий родительскую строку, не будет иметь права на сборку мусора, пока маленькая подстрока не выйдет из области видимости. Это означает, что подстрока может занимать гораздо больше памяти, чем ожидают люди.

Единственный раз, когда способ Java 6 работал значительно лучше, это когда кто-то брал большую подстроку из большой родительской строки, что является очень редким случаем.

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

8
задан MedicineMan 10 June 2009 в 22:25
поделиться

5 ответов

Эта функция в вашей сторонней библиотеке не имеет функции отмены тайм-аута или ? Если так, то это довольно плохой дизайн. Думаю, здесь не будет никакого красивого решения ...

К сожалению, вы не сможете его обойти, кроме использования Win32 API, чтобы убить поток вручную, что определенно не будет чистым. Однако, если эта сторонняя библиотека не дает вам других вариантов, возможно, вам стоит это сделать. Вы захотите использовать функцию TerminateThread , но обратите внимание на предупреждение! Чтобы передать идентификатор потока этой функции, вы должны использовать другой вызов Win32 API (класс Thread не предоставляет его напрямую).

3
ответ дан 5 December 2019 в 19:02
поделиться

Случайная мысль: интересно, можно ли написать вторую сборку как небольшой исполняемый файл консоли, который выполняет это взаимодействие ... запустите ее с помощью Process.Start и зафиксируйте результаты либо через файловую систему или путем перехвата stdout. Затем, если он зависнет, вы можете убить процесс.

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

4
ответ дан 5 December 2019 в 19:02
поделиться

Не лучшее решение, если когда-либо ожидание потока (на любом языке) бесконечно, особенно если вы выполняете внешние вызовы. Всегда используйте соединение с тайм-аутом или спин-блокировку, которая отслеживает состояние разделяемой атомарной переменной, пока оно не изменится или вы не достигнете тайм-аута. Я не специалист по C #, но все это разумные практики параллелизма.

-1
ответ дан 5 December 2019 в 19:02
поделиться

Не уверен, будет ли это приемлемо или приемлемо, но стоит попробовать.

[DllImport("kernel32.dll")]
private static extern bool TerminateThread (Int32 id, Int32 dwexit);

Из документации

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

  • Если целевой поток владеет критической секцией, критическая секция не будет освобождена.
  • Если целевой поток выделяет память из кучи, блокировка кучи не будет be - Release.
  • Если целевой поток выполняет определенные вызовы kernel32, когда он завершается, состояние kernel32 для процесса потока может быть несогласованным.
  • Если целевой поток управляет глобальным состоянием совместно используемой DLL, состояние DLL может быть уничтожено, что повлияет на других пользователей DLL.
2
ответ дан 5 December 2019 в 19:02
поделиться

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

Если нет, отключение потока (через win32) обычно не является хорошей идеей ...

1
ответ дан 5 December 2019 в 19:02
поделиться
Другие вопросы по тегам:

Похожие вопросы: