代码之家  ›  专栏  ›  技术社区  ›  Poul Bak

button.performclick()不等待异步事件处理程序

  •  1
  • Poul Bak  · 技术社区  · 6 年前

    我使用的Windows窗体应用程序有问题 PerformClick 打电话给 async 事件处理程序。似乎事件处理程序没有 await 但马上就回来。我创建了这个简单的应用程序来显示这个问题(它只是一个带有3个按钮的表单,很容易测试自己):

    string message = "Not Started";
    
    private async void button1_Click(object sender, EventArgs e)
    {
        await MyMethodAsync();
    }
    
    private void button2_Click(object sender, EventArgs e)
    {
        button1.PerformClick();
        MessageBox.Show(message);
    }
    
    private void button3_Click(object sender, EventArgs e)
    {
        MessageBox.Show(message);
    }
    
    private async Task MyMethodAsync()
    {
        message = "Started";
        await Task.Delay(2000);
        message = "Finished";
    }
    

    这里有趣的问题是,你认为呢 message 当我单击时显示 Button2 ? 令人惊讶的是, 如您所料,它显示“已开始”,而不是“已完成”。换句话说,它没有 await MyMethod() ,它只是启动任务,然后继续。

    编辑:

    在这个简单的代码中,我可以通过调用 await Method() 直接从button2事件处理程序,如下所示:

    private async void button2_Click(object sender, EventArgs e)
    {
        await MyMethodAsync();
        MessageBox.Show(message);
    }
    

    现在,它等待2秒钟并显示“完成”。

    这是怎么回事?使用时为什么不起作用?

    1. Button.PerformClick

    Button.PerformClick

    1. async void
    1 回复  |  直到 6 年前
        1
  •  4
  •   Ahmed Abdelhameed    6 年前

    async/await PerformClick()

    private async Task MyMethodAsync()
    {
        await Task.Delay(2000);
        message = "Finished";      // The execution of this line will be delayed by 2 seconds.
    }
    
    private void button2_Click(object sender, EventArgs e)
    {
        message = "Started";
        MyMethodAsync();           // Since this method is not awaited,
        MessageBox.Show(message);  // the execution of this line will NOT be delayed.
    }
    

    MyMethodAsync() message

    private async void button1_Click(object sender, EventArgs e)
    {
        await Task.Delay(2000);
        message = "Finished";      // The execution of this line will be delayed by 2 seconds.
    }
    
    private void button2_Click(object sender, EventArgs e)
    {
        message = "Started";
        button1_Click(null, null); // Since this "method" is not awaited,
        MessageBox.Show(message);  // the execution of this line will NOT be delayed.
    }
    

    button1_Click button1_Click(null, null)

    button1.PerfomClick()

    async button2_Click "Edit" section


    this article

    because the return type is void