Остановить / прервать поток класса l oop, C# - PullRequest
2 голосов
/ 02 мая 2020

Я создал тему в c#, но я хочу ее прервать и не знаю, как это сделать.

private void createThread(){
     Thread threadDraw = new Thread(new ThreadStart(myMethod /*Starts a class which loops for a long time*/ ));
     threadDraw.Start();
     if(myBool == false) {theadDraw.Abort();}
}

myMethod запускает класс, работающий на al oop. Дело в том, что я хочу быть в состоянии остановить l oop нажатием клавиши (в моем случае пробел). В настоящее время я пытался с

private void Form1_KeyDown(object sender, KeyEventArgs e)
{
    /* Checks space press, if space press: make myBool = false */
}

Он меняет myBool на false и сам метод работает.

Проблема в том, что createThread() не постоянно проверяет, ложно ли myBool, и поэтому не останавливается.

Я также пытался

private void Form1_KeyDown(object sender, KeyEventArgs e)
{
    /*checks for spacepress, then {threadDraw.Abort()} */
}

, но это тоже не работает, я пытался заменить private на publi c на createThread, но все равно не работает.

Кроме того, я думал о том, чтобы создать KeyDown() -метод внутри класса и иметь перерыв; в l oop, но либо я делаю что-то не так (вероятно) или это невозможно.

Ответы [ 2 ]

1 голос
/ 02 мая 2020

Ваш код if(myBool == false) {theadDraw.Abort();} не работает, потому что вы проверяете это один раз, сразу после запуска потока. И это никогда не проверяется снова (threadDate.Start()' не является блокирующим вызовом).

Но, NET Framework содержит концепцию CancellationToken, которая используется для отмены асинхронного кода.

// Step 1, create a cancellation token:
CancellationTokenSource cancel = new CancellationTokenSource();

// Step 2, reference the token from inside your thread
void ThreadStartMethod() {
   while (!cancel.IsCancellationRequested) {
      // Do work ...
   }
}

// Step 3, cancel the token when you need to
private void Form1_KeyDown(object sender, KeyEventArgs e)
{
    if (e.KeyCode == Keys.Space)
       cancel.Cancel();
}

Примечание: убедитесь, что вы заново создаете токен отмены при каждом запуске потока

0 голосов
/ 02 мая 2020

Я пытался заменить private на publi c на createThread, но все равно не работает.

Это изменит только видимость метода, а не работу method.

Поток выполняет код только один раз. Скорее всего, у вашего myMethod есть oop, который не позволяет его завершить. Abort способ завершения потоков не является изящным (см. Раздел Примечания документации). У вас уже есть условная переменная в вашем коде, myBool, вы можете использовать ее внутри myMethod, чтобы изящно выйти из l oop и позволить потоку завершить себя.

void myMethod() {
    while (myBool && myLogic) { // if myBool is false, short-circuit and leave
        // thread code here.
    }
}

Это поможет нить знает, когда остановиться, выйдя из l oop. Да, и этот подход требует вашего первого Form1_KeyDown метода, в котором вы устанавливаете значение myBool.

Обратите внимание, что вам не нужно использовать while, вы также можете использовать любую другую итеративную структуру, такую ​​как do...while или for l oop. Логика c заканчивается sh l oop, как только myBool становится ложным. Да, break тоже будет работать. : -)

Теперь вернемся к вашему заявлению:

Я хочу иметь возможность отменить его

Если вы хотите, чтобы угроза была отменена правильно прочь, тогда мой подход не будет работать, так как он требует условной проверки перед выполнением l oop. Таким образом, вы можете ожидать задержку в несколько микросекунд - если вашему бизнесу требуется точность в микросекунды, тогда необходимо принудительное завершение потока с помощью Abort.

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