Ответ 1
Нет необходимости сохранять ссылку на объект Thread после запуска потока. Поток продолжает выполняться до тех пор, пока процедура потока не будет завершена.
Так что даже если объект Thread
не найден, поток все равно будет выполняться.
Я упростил приведенный ниже пример для ясности, но я наткнулся на это в живой производственной программе, и я не вижу, как это будет работать!
public class Test
{
static void Main()
{
Counter foo = new Counter();
ThreadStart job = new ThreadStart(foo.Count);
Thread thread = new Thread(job);
thread.Start();
Console.WriteLine("Main terminated");
}
}
public class Counter
{
public void Count()
{
for (int i = 0; i < 10; i++)
{
Console.WriteLine("Other thread: {0}", i);
Thread.Sleep(500);
}
Console.WriteLine("Counter terminated");
}
}
Основная процедура запускает поток счетчика, и основная процедура завершается. Поток счетчика продолжается независимо от следующего выхода.
Main terminated
Other thread: 0
Other thread: 1
Other thread: 2
Other thread: 3
Other thread: 4
Other thread: 5
Other thread: 6
Other thread: 7
Other thread: 8
Other thread: 9
Counter terminated
Моя примерная программа демонстрирует, что, хотя вызывающий класс больше не существует, поток сохраняется до завершения. Однако я понимаю, что после того, как класс окажется вне сферы действия, его ресурсы в конечном итоге будут убраны сборкой мусора.
В моем сценарии реальной жизни поток выполняет массовую рассылку в течение 1-2 часов. Мой вопрос: "Будет ли сбор мусора в конечном итоге уничтожать нить или GC знает, что поток все еще обрабатывается"? Будет ли мой поток электронной почты всегда выполняться до завершения или существует ли опасность, что он закончится ненормально?
Нет необходимости сохранять ссылку на объект Thread после запуска потока. Поток продолжает выполняться до тех пор, пока процедура потока не будет завершена.
Так что даже если объект Thread
не найден, поток все равно будет выполняться.
Посмотрите документацию для System.Threading.Thread.IsBackground
Если поток не является фоновым потоком, он будет отключать приложение до его завершения.
Однако я понимаю, что после того, как класс выходит за рамки, его ресурсы в конечном итоге будут убраны сборкой мусора.
Это можно уточнить:
Как только экземпляр объекта больше не доступен из любого исполняемого кода через управляемую ссылку, он становится пригодным для сбора мусора.
Когда вы создаете новый поток, который выполняет определенный метод объекта, вы делаете это содержимое объекта доступным в течение всего жизненного цикла. GC может только очистить его, если он сможет доказать, что уже невозможно, чтобы ни один из потоков приложений никогда не обращался к этому объекту. Поскольку ваш код по-прежнему может обращаться к экземпляру объекта, он не получает GCed.
Область действия переменной предназначена для компилятора, чтобы определить, доступна ли переменная другими методами. Поток - это запущенный объект, который контролируется управлением процессом.