C# Форма заявки - остановка текущего процесса нажатием другой кнопки - PullRequest
1 голос
/ 06 апреля 2020

Можно ли остановить текущий процесс нажатием кнопки в Windows форме приложения?

  1. Например, скажем, есть 2 кнопки: «СТАРТ» и «СТОП»
  2. Когда вы нажимаете «START», он начинает бесконечно l oop, печатая числа от 1 до бесконечности.
  3. Когда я нажимаю «STOP», процесс должен остановиться в этот момент.
  4. Но проблема в том, что я не могу нажать кнопку «СТОП», так как она не позволяет мне, так как идет непрерывный процесс.

Есть ли способ преодолеть это?

Я знаю, что есть что-то под названием «MethodInvoker», но я понятия не имею, как это работает или имеет к этому отношение.

    private bool keepRunning = true;

    public Form1()
    {
        InitializeComponent();
    }

    private void StartBtn_Click(object sender, EventArgs e)
    {
        var number = 1;
        while (keepRunning)
        {
            Thread.Sleep(1000);
            MesgeLabel.Text = "" + number++;
        }
    }

    private void StopBtn_Click(object sender, EventArgs e)
    {
        //Cannot even click this button
        keepRunning = false;
        //or
        Application.Exit();
    }

Ответы [ 3 ]

1 голос
/ 06 апреля 2020

Когда вы нажимаете кнопку «Пуск», код, который запускается и печатает числа, будет выполняться в потоке пользовательского интерфейса. (из вашего объяснения я предполагаю, что все, что у вас есть, - это обработчик сообщений для события нажатия кнопки и ничего более. Например: не настраивать отдельный поток.).

Запуск бесконечного l oop на Пользовательский поток означает, что у вас больше нет времени на обработку других сообщений. (поток, отвечающий за обработку сообщений пользовательского интерфейса, застрял в вашем бесконечном l oop.)

Итак, чтобы иметь возможность нажать кнопку «Стоп», вам нужно запустить код с бесконечный l oop в другом потоке или в другом процессе. Это то, что Арджун пытается тебе сказать. (если вы хотите, чтобы код в бесконечной l oop обращался к ресурсам из вашего приложения формы, вам нужен поток. [поток находится внутри процесса приложения форм.])

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

0 голосов
/ 06 апреля 2020

РЕДАКТИРОВАНИЕ 1:

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

проверьте Control.InvokeRequired

if(myLabel.InvokeRequired)
    myLabel.Invoke(new Action(() => myLabel.Text = newText));
else
    myLabel.Text = newText;

Вы можете запустить Task, предоставив CancellationToken и отменить операцию при нажатии кнопки остановки.

Задача выполнит бесконечный l oop в другом потоке, и ваш основной поток (поток пользовательского интерфейса) не должен быть затронут и должен быть доступен.

Попробуйте это:

/*
    Please add these on top of your form class

    using System.Diagnostics;
    using System.Threading;
    using System.Threading.Tasks;
*/

public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();
    }

    CancellationTokenSource cancellationTokenSource;
    CancellationToken cancellationToken;

    private void CountToInfinity()
    {
        while (true)
        {
            cancellationToken.ThrowIfCancellationRequested();

            Debug.WriteLine(new Random().Next());
        }
    }

    private async void button1_Click(object sender, EventArgs e)
    {
        if (cancellationTokenSource == null)
        {
            cancellationTokenSource = new CancellationTokenSource();
            cancellationToken = cancellationTokenSource.Token;
            Task.Run((Action)CountToInfinity, cancellationToken);
        }
    }

    private void button2_Click(object sender, EventArgs e)
    {
        if (cancellationTokenSource != null)
        {
            cancellationTokenSource.Cancel();
            cancellationTokenSource.Dispose();
            cancellationTokenSource = null;
        }
    }


}
0 голосов
/ 06 апреля 2020

Если вы создали новый процесс, вы можете вызвать метод kill.

Process myProcess = Process.Start("Notepad.exe")//starts new process
myProcess.Kill();// kills the process. save reference to myProcess and call kill on STOP button click

Если вы начали новый поток, вызовите метод abort, чтобы остановить поток.

Thread thread = new Thread(new ThreadStart(method)); 
thread.Start(); 
thread.Abort(); // terminates the thread. call abort on STOP button click
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...