簡易まとめ
Taskを使えば以下のコードで出来ます。処理を止めずにMsgBoxを出し、メッセージボックスのリザルトを受け取ることも出来ます(後述)。
Task.Run(Sub() MsgBox("Async") End Sub)
やること
WindowsフォームアプリではMsgBoxを用いてメッセージを伝える場面が有りますが、メッセージを出した場合そのメッセージが消えるまで処理が止まるため困る場面が有ります。
対処法をググると『応答不要のメッセージボックスを出したい』などがヒットしますが、情報が古かったのでTaskを使ったやり方を書きます。
普通にやると
以下のコードでは、MsgBoxのOKを押さなければForm1が表示されません。
Public Class Form1 Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load MsgBox("normal") End Sub End Class
Taskを使う
以下のコードではForm1のロード時にMsgBoxを出し、かつ回答無しでForm1が立ち上がります。
Public Class Form1 Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load Task.Run(Sub() MsgBox("Async") End Sub) End Sub End Class
応用
以下は応用です。
別の場所で閉じられるのを待つ
タスクを共有することで、メッセージボックスが閉じられなければ諸々を操作できないようにすることも出来ます。
以下のコードではボタン1を押したときはTaskが完了している(=MsgBoxが閉じられている)かを見てメッセージを、ボタン2を押した場合Taskが完了するまで待ってからメッセージを出しています。
Public Class Form1 Private tsk As Task = Nothing Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load tsk = Task.Run(Sub() MsgBox("Async") End Sub) End Sub Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click Dim str = If(tsk.IsCompleted, "ボックスは閉じています", "ボックスは開いています") MsgBox(str) End Sub Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click tsk.Wait() MsgBox("ボックスが閉じられました") End Sub End Class
回答を受け取る
Taskを使った上で回答を受け取る場合は以下のように行います。
Task.ResultはTask#Waitを呼び出すのと同様にTaskが完了するまで待った上で値を入れ、処理を行ってくれます。
Public Class Form1 Private tsk As Task(Of MsgBoxResult) = Nothing Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load tsk = Task.Run(Function() As MsgBoxResult Return MsgBox("Async", MsgBoxStyle.OkCancel) End Function) End Sub Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click MsgBox(tsk.Result.ToString) End Sub End Class