防止在异步事件中引发下一个事件

时间:2014-08-06 08:19:33

标签: c# .net winforms task-parallel-library async-await

执行GetDataAsync时,在textbox1_Leave事件结束之前引发textBox1_Validating事件。我该怎样做才能防止这种情况发生?

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;
    }
}

2 个答案:

答案 0 :(得分:2)

来自Control.Validating

  

事件按以下顺序发生:

     
      
  1. 输入

  2.   
  3. 的GotFocus

  4.   
  5. 离开

  6.   
  7. 验证

  8.   
  9. 验证

  10.   
  11. 引发LostFocus

  12.   

awaitControl.Leave内时,你让UI消息泵继续执行,因此它会处理下一个事件。如果您想等到Leave完成,请同步运行您的方法。

答案 1 :(得分:1)

控件的Validating进程是一个同步进程,在继续之前,您不能等到从异步方法返回。 async / await的要点是在您等待异步方法的结果时允许UI继续,因此一旦您在await事件中Leave,控件就会假定它#39; s完成并继续使用事件链的其余部分。

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();
    }
}