我正在为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
(在它实际发送电子邮件之前),并且在睡眠期间关闭了该表单,最终电子邮件被发送了。
为什么会这样?
即使关闭其父进程后,也会执行异步查询吗?
答案 0 :(得分:1)
当诸如事件处理程序之类的async
方法命中await
时,它将返回给调用方。返回了等待的方法(IsSomethingValid
或SendEmail
之后,将执行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;
}
即使关闭其父进程后,也会执行异步查询吗?
否,或者至少不是延续。如果您发送电子邮件并退出应用程序,则不一定会阻止电子邮件的发送。