В программе С# у меня есть 2 потока, кроме основного потока. Когда пользователь закрывает форму, я хочу завершить один из потоков из основного потока. Как мне это сделать?. Пожалуйста, предоставьте мне код, если это возможно.
Пожалуйста, не используйте Thread.Abort
, как рекомендовано другими ответами до сих пор, если вы не хотите, чтобы ваша программа находилась в неизвестном состоянии (см. статьи Ian Griffiths и Chris Sells для получения дополнительной информации). Если закрытие формы должно фактически убивать приложение, вы, вероятно, все в порядке, но в этом случае я бы рекомендовал использовать фоновый поток в любом случае, который автоматически погибнет, когда все потоки переднего плана завершатся.
От Джо Даффи "Параллельное программирование в Windows" :
Существует две ситуации, когда прерывания потока всегда безопасны:
- Основной целью прерывания потока является срыв потоков во время CLR AppDomain разгружается. [...]
- Синхронные прерывания потока безопасны, при условии, что абоненты ожидают исключение, которое должно быть выбрано из метода. [...]
Все другие применения прерываний потоков в лучшем случае сомнительны. [...] Хотя прерывания потока теоретически более безопасны, чем другие прерывания потока механизмов, они все еще могут возникать в неподходящие времена, что приводит к нестабильности и коррупции, если они используются без особого внимания.
(Синхронные прерывания потока - это когда поток прерывается сам, а не прерывается другим потоком.)
Для изящного выключения (без риска попадания в нечетные состояния) используйте флаг, который периодически устанавливается из формы и проверяется из других потоков - учет модели памяти во внимание (например, либо делая флаг изменчивым, либо используя блокировку каждый раз вы его тестируете или устанавливаете). Для примера см. Статью статьи по теме.
Убийство потоков из других потоков - это почти всегда плохая идея. Правильный способ сделать это - передать конец потока, а затем дождаться его.
Это потому, что потоки должны полностью отвечать за свои собственные ресурсы настолько, насколько это практически возможно, и это включает их продолжительность жизни.
Это не должно быть сложным, простая периодическая переменная, которая может быть задана любым потоком и периодически читается другим потоком (это не совсем на любом языке, но вы должны получить идею, если знаете C ):
int exitThread1 = false;
static void Thread1 (void) {
while (!exitThread1) {
// do stuff
}
}
static void mummyProc (void) {
int tid1 = startThread (Thread1);
// dum de dum de dum ...
exitThread1 = true;
joinThread (tid1);
}
Если вы хотите убить нить, которую вы начали, я бы предложил сохранить ссылку на нее, например, личное поле. Когда приложение (или поток) заканчивается, вы можете просто вызвать Thread.Abort()
в этом потоке.
Например:
private Thread _myWorker;
void doSomething()
{
_myWorker = new Thread(...);
_myWorker.Start();
}
void killWorker()
{
_myWorker.Abort()
}
Вы должны заметить, что тогда вы вызываете Abort()
в потоке, он будет вызывать исключение ThreadAbortException, которое вы должны поймать внутри вашего рабочего кода и обрабатывать для очистки и т.д. Подробнее см. Thread.Abort
Кроме того, когда ваше приложение отключает свой основной поток (цикл сообщений, aka Application.Run), дочерние потоки также будут отключены.