【问题标题】:What happens when the user closes a form performing an async task in an async event handler?当用户关闭在异步事件处理程序中执行异步任务的表单时会发生什么?
【发布时间】:2019-01-10 12:25:12
【问题描述】:

我正在为 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";
   }
}

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

为什么会这样?

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

【问题讨论】:

  • 除非你停止你等待的任务,否则它会一直持续到异常或结束。一旦你调用SendEmail(),它将尝试完成,除非你provide cancellation(然后你可以在表单关闭事件中执行取消)。
  • 如果数据已经发送到服务器,即使他停止这显然也无济于事
  • 您认为这是一个问题吗?通常它会被认为是一个特性。
  • async void 通常被描述为“一劳永逸”。好吧,你被解雇了,只是因为你忘记了它并不意味着它不会继续。
  • 这和臭名昭著的 Application.DoEvents() 一样有效。众所周知,有时它不会因为难以理解的异常而炸毁程序。因为 Text 属性有些特殊,所以您将侥幸逃脱,它实际上并不会在处理 Label 控件后尝试更新它。不完全是一个功能。

标签: c# winforms asynchronous


【解决方案1】:

async 方法(例如您的事件处理程序)遇到await 时,它将返回给调用者。一旦 awaitable 方法(IsSomethingValidSendEmail)返回,async 方法(btn_ButtonClick)的剩余部分将被执行。

在可等待方法(IsSomethingValidSendEmail)返回之前关闭表单这一事实并不会阻止 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;
}

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-01-15
    • 2016-04-05
    • 2019-04-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多