Как убить поток мгновенно в C #? - PullRequest
47 голосов
/ 25 августа 2009

Я использую метод thread.Abort для удаления потока, но он не работает. Есть ли другой способ завершить поток?

private void button1_Click(object sender, EventArgs e)
{
    if (Receiver.IsAlive == true)
    {
        MessageBox.Show("Alive");
        Receiver.Abort();
    }
    else
    {
        MessageBox.Show("Dead");
        Receiver.Start();
    }
}

Я использую это, но каждый раз, когда я получаю статус Alive, Receiver - это моя глобальная тема.

Ответы [ 6 ]

68 голосов
/ 25 августа 2009

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

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

32 голосов
/ 20 января 2013

Вы можете убить мгновенно, сделав это так:

private Thread _myThread = new Thread(SomeThreadMethod);

private void SomeThreadMethod()
{
   // do whatever you want
}

[SecurityPermissionAttribute(SecurityAction.Demand, ControlThread = true)]
private void KillTheThread()
{
   _myThread.Abort();
}

Я всегда им пользуюсь и у меня работает :) 1004 *

20 голосов
/ 25 августа 2009

Сначала вы должны согласовать метод завершения потока. Например, значение running_ valiable, которое поток может проверить и выполнить.

Код основного потока должен быть заключен в блок исключения, который перехватывает и ThreadInterruptException, и ThreadAbortException, которые будут аккуратно приводить в порядок поток при выходе.

В случае ThreadInterruptException вы можете проверить переменную running_, чтобы увидеть, следует ли вам продолжить. В случае ThreadAbortException вы должны немедленно привести в порядок и выйти из процедуры потока.

Код, который пытается остановить поток, должен сделать следующее:

running_ = false;
threadInstance_.Interrupt();
if(!threadInstance_.Join(2000)) { // or an agreed resonable time
   threadInstance_.Abort();
}
8 голосов
/ 25 августа 2009

поток будет убит, когда он завершит свою работу, поэтому, если вы используете циклы или что-то еще, вы должны передать переменную потоку, чтобы остановить цикл после того, как поток будет завершен.

5 голосов
/ 25 августа 2009

C # Thread.Abort НЕ гарантирует мгновенного прерывания потока. Вероятно, это будет работать, когда поток вызывает Abort для себя, но не тогда, когда поток вызывает другой.

Пожалуйста, обратитесь к документации: http://msdn.microsoft.com/en-us/library/ty8d3wta.aspx

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

0 голосов
/ 20 ноября 2014
    private void ResumeButton_Click(object sender, RoutedEventArgs e)
    {
        Task.Factory.StartNew(() =>
        {
            Application.Current.Resources["AutoPilotThreadStatus"] = true;
            Thread.CurrentThread.Name = "ResumeAutoPilot";
            Thread.CurrentThread.IsBackground = true;
            AutoPilotHandler.ResumeAutoPilot();
        });
    }

    public static void ResumeAutoPilot()
    {
        while ((bool)Application.Current.Resources["AutoPilotThreadStatus"])
        {
            CheckAutoPilotThreadStatus();
            var searchYoutube = YoutubeHandler.Search("small truck");
            CheckAutoPilotThreadStatus();
            SaveVideosToDatabase(searchYoutube);
            CheckAutoPilotThreadStatus();
        }
    }

    public static void CheckAutoPilotThreadStatus()
    {
        if (!(bool)Application.Current.Resources["AutoPilotThreadStatus"])
        {
            KillCurrentThread();
        }
    }

    public static void KillCurrentThread()
    {
        Thread.CurrentThread.Abort();
    }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...