Следует ли всегда ссылаться на текущий объект Thread в С#?

Или можно сделать что-то вроде этого:

new Thread( new ThreadStart( delegate { DoSomething(); } ) ).Start();

?

Кажется, что я помню, что при таком сценарии объект Thread был бы собран мусором, но основной поток ОС продолжал работать до тех пор, пока не будет передан конец делегата. Я в основном ищу функциональность ThreadPool, но не хочу, чтобы потоки были фоновыми потоками (т.е. Я хочу, чтобы они поддерживали приложение).

Обновление:. По словам Джейсона, CLR фактически сохраняет внутреннюю ссылку на объект Thread во время работы, поэтому он не будет собирать мусор до тех пор, пока поток не выйдет.

Ответ 1

Как правило, я обнаружил, что если мне нужно напрямую запустить новый поток так, как вы в своем примере, а не захватывать его из пула потоков, то это длинный поток, и мне понадобится ссылка на него позже убить его, контролировать его и т.д. Для коротких потоков, таких как вызов IO в фоновом потоке и т.д., я всегда использую поток потока потоков (обычно косвенно через вызов метода someDelete.BeginBlah(...)). При использовании потока пула потоков, подобного этому, я предпочитаю НЕ хранить ссылку. Я не знаю, может ли другой программист ненадлежащим образом использовать ссылку на этот поток. Если мне не нужна ссылка, я не буду держать ее вокруг, чтобы загромождать код.

Изменить: Чтобы ответить на ваши изменения о потоках, собранных мусором, это не произойдет во время работы потока. CLR сохраняет ссылку на каждую текущую нить. Объект, представляющий поток, НЕ будет собран.

Ответ 2

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

Ответ 3

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

И, во вторую часть, нет, он не будет GC'd во время его работы; потоки - это объекты уровня корня, из которых GCtor будет преследовать ссылки. Экземпляр Thread будет только GCd, если он больше не доступен ни одному запущенному потоку, включая тот, который вы начинаете с него.

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

Ответ 4

Возможно, было бы неплохо задать вопрос: "Как часто эта нить запускается?" Является ли это для каждого приложения, для класса, для каждого объекта или для вызова для каждого метода? Это может сообщить вам, какую переменную (если есть) хранить в ней.

Ответ 5

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

Так честно, вы можете сделать это по-своему, так что ответ действительно сводится к предпочтению стиля кода.

Ответ 6

В дополнение к тому, что "m3rLinEz" разместил выше, еще один откат - если в вашем потоке возникает какое-либо исключение, будет сложно даже обнаружить такие случаи.