winforms C#窗体应用程序执行任务,运行将停止执行其余代码

cxfofazt  于 2022-11-16  发布在  C#
关注(0)|答案(1)|浏览(251)

代码的借口,这是一个烂摊子,但我试图找出事情没有太多的使用谷歌。

问题:我有一个OnKeyDown方法,它开始把屏幕上的正方形向右移动,如果用户按下A让它停下来并向左移动,我真的不知道该怎么做。我在这里做,但我想如果我使用一个Task.Run,我可以监听其他输入,如果一个键被按下,它可以返回true,并从while循环中断,我会调用另一个方法来左移。这可能是一个非常错误的方法,但我真的被困在这里了,我还不知道另一种方法来做这件事。

提前感谢。

添加所有编码:这里的其他部分只有绘制Grid方法和OnPaint方法

第一个

s4chpxco

s4chpxco1#

代码的问题不在于Task.Run,而在于您阻止了UI正确响应消息泵上的所有更新。
此代码:

var t1 = Task.Run(() =>
{
    if (ke.KeyCode == Keys.D)
        return true;
    else return false;
});

if (t1.Result == true)
    break;

相当于:

if (ke.KeyCode == Keys.D)
    break;

Task在这里没有做任何有价值的事情。
你的问题是while循环没有将控制权返回给消息泵。你需要一个计时器来完成你的动作,而不是一个循环。
具体操作如下:

private System.Windows.Forms.Timer _timer = null;
protected override void OnKeyDown(KeyEventArgs ke)
{
    base.OnKeyDown(ke);

    if (ke.KeyCode == Keys.Escape)
    {
        this.Close();
    }

    if (_timer == null)
    {
        _timer = new System.Windows.Forms.Timer();
        _timer.Enabled = false;
        _timer.Interval = Velocity;
        _timer.Tick += (s, e) =>
        {
            this.X =
                this.X > this.NumCells * 2
                ? 1
                : this.X + this.MoveX;
        };
    }

    if (ke.KeyCode == Keys.D)
    {
        _timer.Enabled = !_timer.Enabled;
    }
}

启用时,定时器每Velocity毫秒触发一次,并更新this.X。按D键可切换定时器的开关。简单。

相关问题