投稿者 るきお  (社会人) 投稿日時 2020/3/22 21:28:48
たとえば、こんな感じでしょうか。30分待つのは大変なので、仮に30秒にしました。
Private Sub buttonA_Click(sender As Object, e As EventArgs) Handles buttonA.Click
    '30秒後にTickイベントを発生させるタイマーを作成。 
    Dim timer As New Timer With {.Interval = 30 * 1000, .Enabled = True}

    '非同期でProcessBを実行する処理を作成し、Tickイベント時に実行するようにしておく。 
    Dim task As New Task(Sub() ProcessB(timer))
    AddHandler timer.Tick, Sub(s, args) task.Start()

End Sub

Private Sub ProcessB(timer As Timer)
    timer.Enabled = False
    timer.Dispose()

    MsgBox("処理Bを実行しました。")
End Sub

Private Sub buttonC_Click(sender As Object, e As EventArgs) Handles buttonC.Click

    '50秒後にTickイベントを発生させるタイマーを作成。 
    Dim timer As New Timer With {.Interval = 50 * 1000, .Enabled = True}

    '非同期でProcessDを実行する処理を作成し、Tickイベント時に実行するようにしておく。 
    Dim task As New Task(Sub() ProcessD(timer))
    AddHandler timer.Tick, Sub(s, args) task.Start()

End Sub

Private Sub ProcessD(timer As Timer)
    timer.Enabled = False
    timer.Dispose()

    MsgBox("処理Dを実行しました。")
End Sub


でも、この機能だけ見るとウィンドウを閉じられたらすべてが終わってしまいますし、処理Bで想定外のエラーが発生してプログラムが終了してしまうと、その後実行される予定だった処理Dが巻き添えを食って実行されなくなるなど、あまり構造が良くないように思います。

Windowsのタスクスケジューラーでも似たようなことができるのでそちらの利用を検討されてはどうでしょうか?

非同期で実行する処理B、処理Dもこの例では非常にシンプルな処理なのでこれで済んでいますが、戻り値やエラーハンドリングや、UIの更新などいろいろ考え出すととても大変です。とても人に薦められるプログラムではありません。