Манипулирование потоком из другого потока

2

В программе С# у меня есть 2 потока, кроме основного потока. Когда пользователь закрывает форму, я хочу завершить один из потоков из основного потока. Как мне это сделать?. Пожалуйста, предоставьте мне код, если это возможно.

Теги:
multithreading

3 ответа

4
Лучший ответ

Пожалуйста, не используйте Thread.Abort, как рекомендовано другими ответами до сих пор, если вы не хотите, чтобы ваша программа находилась в неизвестном состоянии (см. статьи Ian Griffiths и Chris Sells для получения дополнительной информации). Если закрытие формы должно фактически убивать приложение, вы, вероятно, все в порядке, но в этом случае я бы рекомендовал использовать фоновый поток в любом случае, который автоматически погибнет, когда все потоки переднего плана завершатся.

От Джо Даффи "Параллельное программирование в Windows" :

Существует две ситуации, когда прерывания потока всегда безопасны:

  • Основной целью прерывания потока является срыв потоков во время CLR AppDomain разгружается. [...]
  • Синхронные прерывания потока безопасны, при условии, что абоненты ожидают исключение, которое должно быть выбрано из метода. [...]

Все другие применения прерываний потоков в лучшем случае сомнительны. [...] Хотя прерывания потока теоретически более безопасны, чем другие прерывания потока механизмов, они все еще могут возникать в неподходящие времена, что приводит к нестабильности и коррупции, если они используются без особого внимания.

(Синхронные прерывания потока - это когда поток прерывается сам, а не прерывается другим потоком.)

Для изящного выключения (без риска попадания в нечетные состояния) используйте флаг, который периодически устанавливается из формы и проверяется из других потоков - учет модели памяти во внимание (например, либо делая флаг изменчивым, либо используя блокировку каждый раз вы его тестируете или устанавливаете). Для примера см. Статью статьи по теме.

  • 0
    Чтобы закрыть форму у меня есть соответствующее событие. Я назвал поток, который я хочу прекратить, как SecondThread. Однако я не могу вызвать SecondThread. Есть что-то, чего мне здесь не хватает. Более того, если какой-либо поток может прервать сам себя, это упростит ситуацию, потому что я предпочитаю использовать концепцию флагов, как вы указали.
  • 0
    Вы просто убедитесь, что у него есть доступ к общему фрагменту данных, и что он регулярно опрашивает его, чтобы узнать, должен ли он завершить работу. Конечно, вы можете сделать это только в том случае, если вы сами управляете тем, что делает поток.
Показать ещё 2 комментария
2

Убийство потоков из других потоков - это почти всегда плохая идея. Правильный способ сделать это - передать конец потока, а затем дождаться его.

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

Это не должно быть сложным, простая периодическая переменная, которая может быть задана любым потоком и периодически читается другим потоком (это не совсем на любом языке, но вы должны получить идею, если знаете 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);
}
1

Если вы хотите убить нить, которую вы начали, я бы предложил сохранить ссылку на нее, например, личное поле. Когда приложение (или поток) заканчивается, вы можете просто вызвать Thread.Abort() в этом потоке.

Например:

private Thread _myWorker;

void doSomething()
{
    _myWorker = new Thread(...);
    _myWorker.Start();
}

void killWorker()
{
    _myWorker.Abort()
}

Вы должны заметить, что тогда вы вызываете Abort() в потоке, он будет вызывать исключение ThreadAbortException, которое вы должны поймать внутри вашего рабочего кода и обрабатывать для очистки и т.д. Подробнее см. Thread.Abort

Кроме того, когда ваше приложение отключает свой основной поток (цикл сообщений, aka Application.Run), дочерние потоки также будут отключены.

  • 0
    Дочерние потоки будут автоматически закрываться, только если они являются фоновыми. Потоки переднего плана могут жить после завершения основного потока.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню