防止在异步事件中引发next事件

本文关键字:事件 next 异步 | 更新日期: 2023-09-27 18:16:41

当GetDataAsync执行时,在textbox1_Leave事件完成之前引发textbox1_validation事件。我怎样才能避免这种情况呢?

public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();
    }
    private bool IsValid = true;
    private async void textBox1_Leave(object sender, EventArgs e)
    {
        MessageBox.Show("Working");
        ServiceReference1.Service1Client client = new ServiceReference1.Service1Client();
        IsValid = await client.CheckUser(textBox1.Text);
    }
    private void textBox1_Validating(object sender, CancelEventArgs e)
    {
        if(IsValid)
            MessageBox.Show("Welcome!");
        else
            e.Cancel = true;
    }
}

防止在异步事件中引发next事件

From Control.Validating:

事件按以下顺序发生:

  1. 输入
  2. GotFocus

  3. 离开
  4. 验证
  5. 验证
  6. LostFocus

当您在Control.Leave中使用await时,您让UI消息泵继续执行,因此它处理下一个事件。如果您想等待Leave完成,请同步运行您的方法。

控件的Validating进程是一个同步进程,你不能让它等到你从异步方法返回后再继续。async/await的要点是允许UI继续,而你等待你的异步方法的结果,因此一旦你在Leave事件中await,控制假定它已经完成,并继续与事件链的其余部分。

Validating事件应该用于执行同步验证,如果你需要服务器验证,那么你只需要接受输入的文本有效,然后Validated事件,然后你可以发送你的请求

private bool IsValid = false;
private void textBox1_Validated(object sender, EventArgs e)
{
    this.ValidateUser(textBox1.Text);
}
private async void ValidateUser(string username)
{
    ServiceReference1.Service1Client client = new ServiceReference1.Service1Client();
    IsValid = await client.CheckUser(textBox1.Text);
    if (IsValid) {
        MessageBox.Show("Welcome!");
    } else {
        MessageBox.Show("Invalid Username, try again!");
        textBox1.Focus();
    }
}