- В конце того времени, перестает ли существовать happyThread? Или это все еще там в Примере? Или вы можете сохранить его или что-то ??
Когда функция, вызываемая в потоке (в данном случае LongTest
), заканчивает, жизненный цикл потока заканчивается. Поток по-прежнему существует до тех пор, пока у вас есть ссылка на него в happyThread
(вы можете убедиться сами! happyThread.ManagedThreadId
по-прежнему будет возвращать идентификатор потока, даже после его завершения), но его нельзя перезапустить. Вы можете проверить состояние потока, вызвав happyThread.ThreadState
(который в этот момент вернет stopped
).
Можем ли мы теперь "изменить" содержимое потока на
happyThread.newStuff( ShortTest());
happyThread.StartAgain();
Нет, вы не можете. Вы не можете связать новую функцию с потоком, который уже завершен, и если вы попытаетесь вызвать happyThread.Start()
для нее снова, она выдаст ThreadStateException Thread has already been started.
.
Могу ли я просто снова запустить ShortTest только в другой новой теме?
Да. Вам нужно будет запустить ShortTest
для new Thread(ShortTest)
(или вы можете просто добавить его в конец метода LongTest()
. Любой новый метод, запущенный в потоке, будет выполняться в этом потоке). Однако вы можете вызвать новый поток на старый happyThread
. так что happyThread = new Thread(ShortTest())
будет снова счастлив! Вы даже можете начать новый поток в happyThread
до того, как закончится первый поток. так
Thread happyThread = new Thread(LongTest());//say this runs for 1 minute
happyThread.Start();
happyThread = new Thread(ShortTest());//this will start without a problem
happyThread.Start();
И с радостью начнется. Обратите внимание, что это не должно быть сделано на самом деле. Это приведет к потере ссылки на поток, выполняющий LongTest
. (И несмотря на то, что сначала вызывается LongTest
, ShortTest
может на самом деле начать работать первым, если этот поток случится первым ... это действительно далеко от идеала, но просто хотел показать, что возможно . )
будет вызывать short_function для последующего доступа к этому значению?
Да, давайте предположим, что int k
является общедоступным и глобальным и работает только в основном потоке. Вы можете установить его значение от long_function
до 42, а затем прочитать значение int k
из short_function
в потоке , отличном от , если хотите. Теперь обратите внимание, что вы должны быть осторожны с установкой / получением переменных в нескольких потоках, чтобы предотвратить условия гонки .
Если, однако, вы определите int k
внутри метода, работающего в отдельном потоке, он выйдет из области видимости, когда поток умрет, точно так же, как любая переменная, инициализированная внутри функции, когда функция закончится.
Вы можете использовать ключевое слово volatile
, чтобы указать, что переменная может быть изменена несколькими потоками. Msdn docs
если вам нужно запустить миллионы маленьких заданий ...
Если вы будете запускать / закрывать большое количество потоков, вы, вероятно, захотите использовать ThreadPools
Можете ли вы как-то "повторно использовать" тему? Можете ли вы снова войти в нее?
Так что все сводится к нет. Как только поток умирает, он не может начать снова, также посмотрите этот пост об этой конкретной теме.
Однако в качестве альтернативы вы можете поддерживать поток в течение всего времени работы приложения, если вы знаете, что будете вызывать его много или даже постоянно (например, я использую это для поддержания TCP-соединения в фоновом режиме). это должно быть всегда доступно). Это можно сделать так:
Void Start()
{
Thread happyThread = new thread(() => KeepAlivethread(1000));//short, easy way to create a delegate so you can pass parameters to your thread aswell!
happyThread.Start();
}
volatile bool keepThreadAlive = true;//volatile because it may be accessed from another thread
private void KeepAliveThread(int timeout)
{
Debug.Log("Thread started with id: " + Thread.CurrentThread.ManagedThreadId);
while (keepThreadAlive)
{
//do something, maybe have an event that calls to ShortTest.
Thread.Sleep(timeout);
}
Debug.Log("Thread terminating with id: " + Thread.CurrentThread.ManagedThreadId);
}
Теперь этот поток будет работать в фоновом режиме до тех пор, пока вы не установите keepThreadAlive = false
, после чего он корректно завершится. (сделайте так, чтобы вам не нужно было thread.Abort()
, что плохо! (подробнее об этом в ответе на предыдущую ссылку в SO)