0

При нажатии кнопки "btn_Close" должна закрываться форма и открываться вторая. По итогу возникают две ситуации:

  1. Форма закрывается и открывается вторая после одного нажатия кнопки "btn_Close".
  2. Для закрытия формы иногда приходится нажимать на "btn_Close" два раза. Причем видно, что после первого нажатия останавливается поток "Thread_ModbusPull" (на форме видно, что останавливается опрос устройств).

Подскажите, пожалуйста, как исключить второй случай. Как я понимаю, я неправильно завершаю потоки.

public Thread? Thread_Examination;
public Thread? Thread_ModbusPull;

private void FormExamination_Load(Object sender, EventArgs e) { Thread_Examination = new Thread(Examination); Thread_Examination.Start();

        Thread_ModbusPull = new Thread(ModbusPulling);
        Thread_ModbusPull.Start();
    }


bool StartThread = true;

public void Examination() { while (StartThread == true) {

            switch (G.Step)
            {
               // Тут пошаговое выполнение с редким использованием Thread.Sleep
            }

        }
    }


int ConStep = 0; bool ValuesPulling = true;

public async void ModbusPulling() { while (ValuesPulling == true) {

            switch (ConStep)
            {
               // Тут цикличный опрос устройства по Modbus TCP c использованием await Task.Delay
            }

        }
    }


private void btn_Close_Click(object sender, EventArgs e) { StartThread = false; ValuesPulling = false;

            G.Step = 0;
            ConStep = 0;


            if (!Thread_Examination.IsAlive && !Thread_ModbusPull.IsAlive)
            {
                this.Close();
            }
    }

Shoroh
  • 21
  • 3
    Если используете асинхронное программирование - используйте. Незачем намешивать в кучу работу с потоками. Ссылка на ответ вверху. В асинхронном методе вместо Thread.Sleep используйте await Task.Delay с указанием токена отмены как в ответе. – aepot Jan 26 '24 at 07:09
  • 1
    В данном случае мне кажется достаточно было бы добавить Thread_Examination.join(); Thread_ModbusPull.join(); после выставления переменных в false. А, блин, да, если второй тред асинхронный должен быть, то проблема глубже, да, не следует смешивать. – CrazyElf Jan 26 '24 at 07:15
  • Возник еще один вопрос. Почему Thread_ModbusPull.IsAlive == false, когда поток явно запущен? – Shoroh Jan 26 '24 at 08:03
  • 1
    @Shoroh А где и как вы это проверяли? Ну и может быть это из-за смешивания асинхронности с многопоточностью. – CrazyElf Jan 26 '24 at 08:39
  • 1
    @CrazyElf Да, Вы правы, убрал async и все заработало. Спасибо всем большое за ответы! – Shoroh Jan 26 '24 at 10:48

0 Answers0