await
で一度イベントハンドラが終了します。その時 e.Cancel
は true
です。
ですのでフォームは閉じません。
しかし e.Cancel
が評価される前にタスクが終了して e.Cancel
が書き換えられるとフォームは閉じます。
追記
わかりにくかったかもしれないので順を追って説明します。
これは System.Windows.Forms.Form
のソースです。
Form.cs
C#
1OnFormClosing(e);
2if (e.Cancel)
3{
4 dialogResult = DialogResult.None;
5}
6else
7{
8 // we have called closing here, and it wasn't cancelled, so we're expecting a close
9 // call again soon.
10 CalledClosing = true;
11}
上記の OnFormClosing(e);
で FormClosing
イベントハンドラを(あれば)呼びます。
ユーザーはハンドラの中で e.Cancel
を設定します。
イベントハンドラが次のようになっている場合
C#
1private async void Form1_FormClosing(object sender, FormClosingEventArgs e)
2{
3 e.Cancel = true;
4 await Task.Run(() =>
5 {
6 return;
7 });
8 e.Cancel = false;
9}
await
によって一度ハンドラが終了するので、次のようなハンドラを指定したのと同じことになります。
C#
1private async void Form1_FormClosing(object sender, FormClosingEventArgs e)
2{
3 e.Cancel = true;
4}
そして同時に次の非同期処理が登録されます。
(実際に実行されるのは同時とは限りません)
C#
1Task.Run(() =>
2{
3 return;
4});
5e.Cancel = false;
この非同期処理は return
のみのタスクを実行し、それが終了すると e.Cancel = false
というタスクを実行しますので、整理すると次の内容とほぼ同じです。
C#
1Task.Run(() =>
2{
3 e.Cancel = false;
4});
さてこの非同期処理がいつ行われるかですが、それは実行してみるまでわかりません。
この処理によって e.Cancel
が書き換えられるわけですが、それが Form.cs
中の
この部分より前に行われると、e.Cancel
は false
となって else
ブロックが実行されます。
また、後に行われたならば真のブロックが実行されます。
重たい処理の場合はおそらく間に合わないので e.Cancel
は true
となります。
二番目の例の場合は間に合うか間に合わないかは状況次第です。
以上が処理の流れとなります。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2018/01/09 03:34
2018/01/09 04:20
2018/01/09 04:22
2018/01/09 04:54
2018/01/09 04:59 編集
2018/01/09 05:03
2018/01/09 05:19