Должен ли я хранить ссылку на поток после его запуска? - PullRequest
6 голосов
/ 26 июня 2011

Я продолжаю читать код и примеры многопоточных приложений. Время от времени я вижу такой фрагмент:

class Program
{
    static void Main(string[] args)
    {
        Console.WriteLine("started");
        Go();
        Console.WriteLine("press [ENTER] to quit");
        Console.ReadLine();
    }

    private static void Go()
    {
        var thread = new Thread(DoSomething);
        thread.Start();
    }

    private static void DoSomething()
    {
        Console.WriteLine("doing something");
    }
}

И меня это продолжает беспокоить: я должен где-то хранить ссылку на (передний план) поток? В конце концов, это локальная переменная внутри Go метода. Следовательно, как только выполнение Go завершено, ссылка на поток должна собираться мусором. Так что, может быть, просто может быть, поток будет GCed во время выполнения?

Изменится ли ответ, если это фоновая нить?

Заранее спасибо!

Ответы [ 3 ]

4 голосов
/ 26 июня 2011

Поток - это один пример объекта, время жизни которого , а не , контролируемого сборщиком мусора. Под капотом это объект операционной системы. Это живо, пока поток выполняет код. Класс Thread - это просто оболочка для него. Другой пример - окно, оно живо, пока ваш код или пользователь не закрывают его. Winforms не требует, чтобы вы содержали ссылку на оболочку класса Form. И вы, как правило, не:

 Application.Run(new Form1());

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

Вы всегда можете заново создать объект Thread из существующего запущенного потока. Вы делаете это с Thread.CurrentThread. И это не обязательно должен быть поток, созданный вами с помощью конструктора Thread. Может использоваться внутри потока пула. Или поток, который не был запущен управляемым кодом. Хороший пример тому - основной поток вашей программы, он был запущен Windows.

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

2 голосов
/ 26 июня 2011

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

Единственное отличие между передним и фоновым потоками состоит в том, что поток переднего плана поддерживает работу среды управляемого выполнения.

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

Источник

2 голосов
/ 26 июня 2011

Согласно этому ответу вам не о чем беспокоиться. GC достаточно умен, чтобы знать, используется ли поток.

Вот статья, объясняющая поведение: http://msdn.microsoft.com/en-us/magazine/bb985011.aspx#ctl00_MTContentSelector1_mainContentContainer_ctl03

...