是否可以通过在Windows窗体应用程序中单击按钮来停止正在进行的进程?
例如,假设有两个按钮,“开始”和“停止”,当你按下“开始”时,它将启动一个无限循环,从1到无穷大打印数字。当我按“停止”时,进程应该停止。但是问题是,我不能按“停止”按钮,因为它不允许我,因为有一个正在进行的过程。
有什么办法可以克服这个问题吗?
我知道有一种叫做"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();
}发布于 2020-04-06 11:36:37
编辑1:
如果需要与UI控件交互,则从后台任务执行此操作将引发无效操作->非法跨线程异常。为了克服这一切,
检查Control.InvokeRequired
if(myLabel.InvokeRequired)
myLabel.Invoke(new Action(() => myLabel.Text = newText));
else
myLabel.Text = newText;您可以通过提供一个Task并在单击“停止”按钮时取消该操作来启动CancellationToken。
该任务将在另一个线程上执行无限循环,您的主线程( UI线程)不应该受到影响,并且应该是可访问的。
试试这个:
/*
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;
}
}
}发布于 2020-04-06 10:53:57
如果您已经生成了一个新的进程,那么您可以调用杀死方法。
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发布于 2020-04-06 11:09:22
当您按下“开始”按钮时,运行并打印数字的代码将在ui线程上运行。(根据您的解释,我假设您所拥有的只是按钮按下事件的消息处理程序,而不是其他任何东西。没有设置分开的线程。)
在ui线程上运行无限循环意味着您没有更多时间处理其他消息。(负责处理ui消息的线程被困在无限循环中。)
因此,为了能够按下“停止”按钮,您需要在不同的线程或完全不同的进程中使用无限循环运行代码。这就是阿尔琼想告诉你的。(如果希望无限循环中的代码访问表单应用程序中的资源,则需要一个线程。线程位于forms应用程序进程中。)
请注意:如果您创建一个线程并在该线程中运行您的数字打印代码,这将不是ui线程。因此,您将无法像在ui线程上那样与窗体控件交互。(也就是说:试图设置windows.text以显示数字很可能会引发异常。)
https://stackoverflow.com/questions/61057876
复制相似问题