Манипулирование потоком из другого потока - PullRequest
2 голосов
/ 21 апреля 2009

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

Ответы [ 3 ]

4 голосов
/ 21 апреля 2009

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

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

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

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

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

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

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

2 голосов
/ 21 апреля 2009

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

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

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

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

Например:

private Thread _myWorker;

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

void killWorker()
{
    _myWorker.Abort()
}

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...