首页 > 解决方案 > 当用户关闭在异步事件处理程序中执行异步任务的表单时会发生什么?

问题描述

我正在为 Windows 窗体编写异步事件处理程序,但我不熟悉 C# 处理某些场景的方式,因为在这种情况下,在异步事件处理程序触发的异步处理期间关闭窗体。

关闭有问题的表单不会终止整个程序,因为该表单是由另一个表单(“主”表单)初始化的。

这就是我正在编写的代码的样子:

private void async btn_ButtonClick(...){
   aLabel.Text = "Validating something ...";
   var isValid = await IsSomethingValid(...);
   if (isValid)
       aLabel.Text = "It's valid";

   else{
       aLabel.Text = "Sending email ...";
       await SendEmail(...);
       aLabel.Text = "Email sent";
   }
}

我已经做了一些测试,甚至在它实际发送电子邮件之前放置了一个很长Thread.Sleep的时间SendEmail,并在睡眠期间关闭表单,电子邮件最终被发送。

为什么会这样?

即使关闭其父进程,异步查询也会被执行吗?

标签: c#winformsasynchronous

解决方案


async诸如事件处理程序之类的方法命中await时,它将返回给调用者。一旦可等待的方法(IsSomethingValidSendEmail)返回,该async方法的剩余部分(btn_ButtonClick)将被执行。

IsSomethingValid在可等待方法 (或) 返回之前关闭表单这一事实SendEmail并不会阻止async方法 ( btn_ButtonClick) 的其余部分被执行。

如果您在表单关闭后不想做任何事情,您可以使用一个标志来跟踪它是否已关闭,例如:

public Form1()
{
    InitializeComponent();
    FormClosed += Form1_FormClosed;
}

private async void btn_ButtonClick(object sender, EventArgs e)
{
    var isValid = await IsSomethingValid();
    if (isValid && !_isClosed) //<--
    {
        MessageBox.Show("!");
    }
}

private void Form1_FormClosed(object sender, FormClosedEventArgs e) => _isClosed = true;

private async Task<bool> IsSomethingValid()
{
    await Task.Delay(5000);
    return true;
}

即使关闭其父进程,异步查询也会被执行吗?

不,或者至少不是延续。如果您发送电子邮件并退出应用程序,这并不一定会停止发送电子邮件。


推荐阅读