Если у вас есть долгоживущая маленькая подстрока короткой, большой родительской строки, большой символ [], поддерживающий родительскую строку, не будет иметь права на сборку мусора, пока маленькая подстрока не выйдет из области видимости. Это означает, что подстрока может занимать гораздо больше памяти, чем ожидают люди.
Единственный раз, когда способ Java 6 работал значительно лучше, это когда кто-то брал большую подстроку из большой родительской строки, что является очень редким случаем.
Ясно, что они решили, что крошечные потери производительности этого изменения перевесили скрытые проблемы с памятью, вызванные старым способом. Определяющим фактором является то, что проблема была скрыта, а не то, что есть обходной путь.
Эта функция в вашей сторонней библиотеке не имеет функции отмены тайм-аута или ? Если так, то это довольно плохой дизайн. Думаю, здесь не будет никакого красивого решения ...
К сожалению, вы не сможете его обойти, кроме использования Win32 API, чтобы убить поток вручную, что определенно не будет чистым. Однако, если эта сторонняя библиотека не дает вам других вариантов, возможно, вам стоит это сделать. Вы захотите использовать функцию TerminateThread
, но обратите внимание на предупреждение! Чтобы передать идентификатор потока этой функции, вы должны использовать другой вызов Win32 API (класс Thread
не предоставляет его напрямую).
Случайная мысль: интересно, можно ли написать вторую сборку как небольшой исполняемый файл консоли, который выполняет это взаимодействие ... запустите ее с помощью Process.Start
и зафиксируйте результаты либо через файловую систему или путем перехвата stdout. Затем, если он зависнет, вы можете убить процесс.
Возможно, немного жестко - и, очевидно, у него есть накладные расходы на порождение процесса - но по крайней мере должно быть возможно его убить.
Не лучшее решение, если когда-либо ожидание потока (на любом языке) бесконечно, особенно если вы выполняете внешние вызовы. Всегда используйте соединение с тайм-аутом или спин-блокировку, которая отслеживает состояние разделяемой атомарной переменной, пока оно не изменится или вы не достигнете тайм-аута. Я не специалист по C #, но все это разумные практики параллелизма.
Не уверен, будет ли это приемлемо или приемлемо, но стоит попробовать.
[DllImport("kernel32.dll")]
private static extern bool TerminateThread (Int32 id, Int32 dwexit);
TerminateThread - опасная функция, которую следует использовать только в самые крайние случаи. Вы должны вызывать TerminateThread только в том случае, если вы точно знаете, что делает целевой поток, и вы контролируете весь код, который целевой поток мог бы запускать во время завершения. Например, TerminateThread может привести к следующим проблемам:
Управляемые потоки не могут напрямую останавливать собственные потоки. Поэтому, если вызов заблокирован в машинном коде, лучшее, что вы можете сделать, - это проверить управляемый поток, а затем завершить его, как только он вернется. Если он никогда не возвращается, может быть, есть версия вызова с тайм-аутом?
Если нет, отключение потока (через win32) обычно не является хорошей идеей ...