【入門編】VB.NETにおけるAsync/AwaitとIProgress(Of T)を用いた非同期処理の進捗率プログレスバー実装 – Visual Basic (VB / VB.NET)解析バイブル

スポンサーリンク

こんにちは。現場で叩き上げられた、少しだけ経験豊富なエンジニアの先輩です。

VB.NETを触っていると、「重い処理を実行している間、画面がフリーズして動かなくなる」という壁に必ずぶつかりますよね。これ、初心者を卒業する最大の関門なんです。

今日は、その「フリーズ」を解消し、さらに「今の進捗状況をプログレスバーに表示する」という、プロの現場でも必須のテクニックを伝授します。これさえマスターすれば、君が書くアプリの品格は一気に上がります。

なぜ「フリーズ」するのか?― 魔法の言葉「Async/Await」の正体

まず前提として、UI(画面)は「メインスレッド」という一本の道の上で動いています。重い計算をその道でやると、画面の描画処理が待たされてしまい、結果として「応答なし」になります。

これを解決するのが `Async`(非同期)と `Await`(待機)です。

  • Async: 「このメソッドは裏で動くよ」という宣言。
  • Await: 「ここから先は裏で計算させるから、終わるまで一旦メインスレッドは解放してね」という指示。

これを使うと、裏で計算している間も画面はスルスル動き、ユーザーはプログレスバーを見ることができるのです。

現場で即戦力!IProgress(Of T) による進捗報告

単に非同期にするだけなら `Task.Run` で十分ですが、進捗率を伝えるには `IProgress(Of T)` インターフェースを使うのがVB.NETの正攻法です。これを使うと、「裏側で計算しているスレッドから、安全にUIスレッドへ値を渡す」という複雑な仕事を .NET が肩代わりしてくれます。

実践コード:プログレスバー連動サンプル

まずはフォームに `ProgressBar1` と `Button1` を配置してください。以下のコードを貼り付ければ、そのまま動きます。

Imports System.Threading

Public Class Form1

‘ ボタンが押されたら処理を開始する
Private Async Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Button1.Enabled = False
ProgressBar1.Value = 0

‘ 1. 進捗報告用のインスタンスを作成
‘ Progress(Of Integer) は、数値を受け取ってUIを更新する箱です
Dim progressIndicator As New Progress(Of Integer)(Sub(percent)
ProgressBar1.Value = percent
End Sub)

‘ 2. 重い処理を非同期で実行(Awaitで完了を待つ)
Await Task.Run(Sub() DoHeavyWork(progressIndicator))

Button1.Enabled = True
MessageBox.Show(“処理が完了しました!”)
End Sub

‘ 3. バックグラウンドで動く重い処理
Private Sub DoHeavyWork(progress As IProgress(Of Integer))
For i As Integer = 1 To 100
‘ ここで時間のかかる処理をシミュレート
Thread.Sleep(50)

‘ 進捗を報告(UIスレッド側へ安全に値を送る)
If progress IsNot Nothing Then
progress.Report(i)
End If
Next
End Sub

End Class

押さえておくべき「3つのポイント」

1. `Async Sub` の罠

イベントハンドラ(ボタンクリック時など)は `Async Sub` でOKですが、それ以外のメソッドで非同期にする場合は `Async Function … As Task` にしましょう。`Sub` にすると例外をキャッチしづらくなるため、現場では `Task` を返すのが鉄則です。

2. UIスレッドのルール

VB.NETでは、「UI部品(ProgressBar等)は、それを作ったスレッドからしか触れない」という絶対的なルールがあります。`IProgress(Of T)` を使えば、このルールを意識せずに、バックグラウンド側から安全に値を送ることができます。もしこれを使わずに直接 `ProgressBar1.Value = …` と書くと、アプリはクラッシュします。注意してくださいね!

3. `Await` の位置

`Await` は、「そのメソッドが終わるまでここを一時停止する」というマークです。`Await` を書き忘れると、非同期処理が完了する前に次の行が実行されてしまい、バグの温床になります。

まとめ:ここをクリアすれば、もう初心者は卒業

最初は `Async/Await` という概念に戸惑うかもしれません。でも、「メインの道を塞がないように、裏道を用意してあげる」というイメージを持ってください。

  • 重い処理は `Task.Run` で裏へ飛ばす。
  • 状況報告は `IProgress(Of T)` でメインに戻す。

このパターンさえ覚えてしまえば、どんなに重いシステム開発でも怖くありません。マクロの記録から一歩踏み出し、自分だけの「動くアプリ」を作れるようになった君なら、きっと素晴らしいエンジニアになれます。

もし動かない箇所があれば、いつでも質問してください。コードの裏側にある「なぜそうするのか」を理解したとき、プログラミングはもっと楽しくなりますよ!

タイトルとURLをコピーしました