我不明白为什么在窗体中使用keywait的async等待在winForm应用程序中的按键事件上得到奇怪的结果。这是我的问题的非常简单的演示。 完整的应用程序:
using System.Drawing;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace WindowsFormsApp1
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
int counter = 0;
private async void Form1_KeyDown(object sender, KeyEventArgs e)
{
await HandleKeypress();
}
private async Task HandleKeypress()
{
switch (counter)
{
case 0:
label1.BackColor = Color.Red;
label2.BackColor = Color.White;
label3.BackColor = Color.White;
break;
case 1:
label1.BackColor = Color.White;
label2.BackColor = Color.Red;
label3.BackColor = Color.White;
break;
case 2:
label1.BackColor = Color.White;
label2.BackColor = Color.White;
label3.BackColor = Color.Red;
label3.Refresh();
await Task.Delay(5000);
break;
}
counter++;
if (counter == 3)
{
counter = 0;
}
}
}
}
窗体KeyPreview处于打开状态,窗体上的KeyDown事件 触发异步方法。当计数器达到3时,计数器从0递增到3,计数器重置为0。根据计数器值0,1,2,共有三个标签,相应的标签背景设置为红色,另外两个标签设置为白色。计数器== 2时有5秒的延迟。如果计数器== 2时我一直按Enter键,我希望标签3变为红色,而其他两个标签重置为白色。然后在5秒钟后,我希望label1恢复为红色,并且序列继续。这不是发生的情况,并且序列变得有些混乱。为什么会发生这种情况。您必须按住一个键。
答案 0 :(得分:0)
那是因为当您在延迟期间按键时,计数器仍为2,因为它在等待延迟完成以进行计数器++。也许如果您移动计数器++,您会得到想要的结果
int counter = 0;
private async void Form1_KeyDown(object sender, KeyEventArgs e)
{
HandleKeypress();
}
private void HandleKeypress()
{
switch (counter)
{
case 0:
label1.BackColor = Color.Red;
label2.BackColor = Color.White;
label3.BackColor = Color.White;
counter++;
break;
case 1:
label1.BackColor = Color.White;
label2.BackColor = Color.Red;
label3.BackColor = Color.White;
counter++;
break;
case 2:
label1.BackColor = Color.White;
label2.BackColor = Color.White;
label3.BackColor = Color.Red;
label3.Refresh();
MyWait();
break;
}
if (counter == 2)
{
counter = 0;
}
}
private async Task MyWait()
{
await Task.Delay(5000);
counter++;
}
答案 1 :(得分:0)
如果您可以在延迟之前设置bool(cancelAction)取消按键,则可以完成所需的操作。
int counter = 0;
bool cancelAction = false;
private async void Form1_KeyDown(object sender, KeyEventArgs e)
{
await HandleKeypress();
}
private async Task HandleKeypress()
{
if (cancelAction)
{
return;
}
switch (counter)
{
case 0:
label1.BackColor = Color.Red;
label2.BackColor = Color.White;
label3.BackColor = Color.White;
break;
case 1:
label1.BackColor = Color.White;
label2.BackColor = Color.Red;
label3.BackColor = Color.White;
break;
case 2:
label1.BackColor = Color.White;
label2.BackColor = Color.White;
label3.BackColor = Color.Red;
label3.Refresh();
cancelAction = true;
await Task.Delay(5000);
cancelAction = false;
break;
}
counter++;
if (counter == 3)
{
counter = 0;
}
}