如何停止一个动作

huangapple go评论89阅读模式
英文:

How to stop an action

问题

I'm trying to learn C# by creating a simple Windows Form Application.
我正在尝试通过创建一个简单的Windows Form应用程序来学习C#。

I have a start button which starts a process inside a while loop when clicked.
我有一个启动按钮,当点击时启动一个循环内的进程。

I also have a stop button and I would want it to stop the while loop initiated when my start button was clicked.
我还有一个停止按钮,我希望它能停止在点击启动按钮时启动的循环。

Problem is, it does not work.
问题是,它不起作用。

I also have another mechanism which is when I press the Esc button it stops the while loop. This mechanism however works fine.
我还有另一种机制,即当我按Esc按钮时停止循环。然而,这种机制运行良好。

This is my code:
这是我的代码:

class Global
{
    public static string PrcStpr = "off";
    public static string KeyVal;
}

public Form1()
{
    InitializeComponent();
    this.KeyPreview = true;
    this.KeyDown += Form1_KeyPress;
}

private void Form1_KeyPress(object sender, KeyEventArgs e)
{
    Global.KeyVal = e.KeyCode.ToString();
}

private void button2_Click(object sender, EventArgs e) //this is my stop button                                                          
{
    Global.PrcStpr = "on";
}

private void button1_Click(object sender, EventArgs e) //this is my start button
{
    Global.KeyVal = "";
    Global.PrcStpr = "off";
    while (Global.KeyVal != "Escape" || Global.PrcStpr != "on")
    {
        richTextBox1.Focus();
        SendKeys.SendWait(" ");
    }
}

Can anyone help me with this please?
有人能帮助我吗?我做错了什么?

英文:

I'm trying to learn C# by creating a simple Windows Form Application.

I have a start button which starts a process inside a while loop when clicked.

I also have a stop button and I would want it to stop the while loop initiated when my start button was clicked.
Problem is, it does not work.
I also have another mechanism which is when I press the Esc button it stops the while loop. This mechanism however works fine.
This is my code:

class Global
{
    public static string PrcStpr = "off";
    public static string KeyVal;
}

public Form1()
{
    InitializeComponent();
    this.KeyPreview = true;
    this.KeyDown += Form1_KeyPress;
}

private void Form1_KeyPress(object sender, KeyEventArgs e)
{
    Global.KeyVal = e.KeyCode.ToString();
}

private void button2_Click(object sender, EventArgs e) //this is my stop button                                                          
{
    Global.PrcStpr = "on";
}

private void button1_Click(object sender, EventArgs e) //this is my start button
{
    Global.KeyVal = "";
    Global.PrcStpr = "off";
    while (Global.KeyVal != "Escape" || Global.PrcStpr != "on")
    {
        richTextBox1.Focus();
        SendKeys.SendWait(" ");
    }
}

Can anyone help me with this please?
What am I doing wrong?

答案1

得分: 1

重要的是要注意只有一个UI线程。这意味着如果UI线程正在进行任何类型的处理,它就无法执行其他任务,比如更新UI或处理按钮按下等。

你当前的代码对我来说没有太多意义。我猜想它只会将一堆消息放入消息队列,但永远不会有机会处理它们,从而使应用程序无响应。

所以,如果你需要执行一些耗时的操作,有几种可能的方法:

  1. 异步处理 - 如果你正在执行IO操作,如从磁盘、数据库或发起某些网络请求读取数据,这是合适的。
  2. 后台处理 - 将执行移到后台线程。这适用于计算密集型操作。这应该使用任务(Tasks)来运行代码,使用取消令牌(CancellationToken)来取消操作。
  3. 定时器 - 创建一个定时器,在定期(或不定期)间隔内运行一些代码。定时器可以在后台线程或UI线程上运行代码。

我猜你想要一个定时器,间隔设为100毫秒?将你的循环内容放在Tick事件的事件处理程序中,并使你的按钮设置Enable属性为true/false。

但是目前并不清楚你实际要做什么。重复设置焦点,或者像这样使用Send Keys,对我来说看起来很奇怪。因此,存在很大的风险,这可能是一个XY问题。

英文:

It is important to note that there is only one UI thread. This means that if the UI thread is doing any kind of processing it cannot do other things, like updating the UI or processing button presses etc.

Your current code does not make much sense to me. I would guess that it will just put a bunch of messages on the message queue, but never get a chance to process them, effectively hanging the application.

So if you need to do something time consuming there are a few possible approaches:

  1. Asynchronous processing- This is appropriate if you are doing IO operations, like reading from disk, a database, or marking some webrequest.
  2. Background processing - Move the execution to a background thread. This is suitable for compute heavy operations. This should use Tasks to run the code and CancellationToken for cancelling.
  3. Timer - Create a timer that runs some piece of code at regular (or non regular) intervals. Timers can run the code either on a background thread or UI thread.

My guess is that you want a timer, with an interval of, say 100ms? Put the contents of your loop in an event handler for the Tick-event, and make your buttons set the Enable property to true/false.

But it is not at all clear what it is you are actually trying to do. Repeatedly setting focus, or using Send Keys like this, seem odd to me. So there is a significant risk that this is a XY-problem.

huangapple
  • 本文由 发表于 2023年6月26日 15:45:08
  • 转载请务必保留本文链接:https://go.coder-hub.com/76554559.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定