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

スポンサーリンク

UIを止めずに「裏側」で仕事をさせる技術:VB.NETでの非同期処理マスタークラス

こんにちは。業務自動化の現場で数々のコードと向き合ってきた皆さんに、今日は「ワンランク上のVB.NETプログラミング」を伝授します。

皆さんが業務ツールを作るとき、こんな経験はありませんか?
「ボタンを押した瞬間、画面が真っ白になってフリーズし、マウスカーソルがぐるぐる回り出す……。」

これは、「UIスレッド」という、画面を描画するためのメイン通りが、重い計算処理で塞がってしまっているからです。プロのエンジニアは、重い処理を「裏道(バックグラウンドスレッド)」に逃がし、かつ「今どれくらい進んでいるか?」を安全にUIへ報告する設計をします。

今回は、`Async/Await`と`IProgress(Of T)`を使って、プログレスバーを滑らかに動かす「プロの作法」を解説します。

1. なぜ「Async/Await」が必要なのか?

VB.NETにおける`Async/Await`は、単にコードを非同期にするための魔法ではありません。「処理の完了を待っている間、UIスレッドを解放する」ための交通整理です。

  • Async: 「このメソッドは裏で動く可能性があるよ」という宣言。
  • Await: 「ここから先は重いから、裏でやってね。終わるまでここで一度中断して、UIを自由にさせよう」という合図。

これを使えば、メインフォームはフリーズすることなく、ユーザーの操作を受け付け続けられます。

2. 進捗状況を安全に伝える「IProgress(Of T)」

昔のVB.NETでは、別スレッドからフォームのプログレスバーを直接操作しようとすると、「スレッド間操作の例外」というエラーで落ちていました。

これを解決するのが `IProgress(Of T)` です。
これは「進捗状況を渡すための安全なパイプ」のようなもの。バックグラウンドからこのパイプに数字を流し込めば、自動的にUIスレッド側で受け取ってUIを更新してくれるという、非常に賢い仕組みです。

3. 実践:滑らかなプログレスバーの実装コード

では、実際に現場で使える設計を見てみましょう。フォームに `ProgressBar1` と `Button1` を配置した状態を想定してください。

Imports System.Threading
Imports System.Threading.Tasks

Public Class MainForm

‘ ボタンクリック時のイベント
Private Async Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
‘ ボタンを無効化して連打を防ぐのがプロの配慮
Button1.Enabled = False
ProgressBar1.Value = 0

‘ 進捗を受け取るためのプログレスオブジェクトを生成
‘ ラムダ式を使って、進捗率(i)が送られてきた時の処理を記述
Dim progress = New Progress(Of Integer)(Sub(i)
ProgressBar1.Value = i
End Sub)

‘ 重い処理を実行(AwaitでUIをブロックしない)
Await Task.Run(Sub() DoHeavyWork(progress))

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

‘ 重い処理の実体(UIには触れないのが鉄則)
Private Sub DoHeavyWork(progress As IProgress(Of Integer))
For i As Integer = 1 To 100
‘ ここで負荷をシミュレーション
Thread.Sleep(50)

‘ パイプ(progress)に進捗を流し込む
progress.Report(i)
Next
End Sub

End Class

コードの重要ポイント:

1. `Task.Run`: CPUをガッツリ使う計算やファイル読み込みは、必ずこの中に入れましょう。
2. `progress.Report(i)`: これが呼び出されると、先ほど定義した「UIを更新するラムダ式」がUIスレッド上で実行されます。スレッド間の競合を気にする必要はもうありません。
3. `Async Sub`: イベントハンドラは`Async Sub`にするのが定石です。

4. 初学者が陥りやすい罠:ここだけは気をつけて!

  • UIへの直接アクセス: `DoHeavyWork`の中で `ProgressBar1.Value = i` を直接書いてはいけません。必ずエラーになります。常に `IProgress` を介してください。
  • 例外処理: 非同期処理の中で発生したエラーは、`Await`している場所でキャッチできます。必ず `Try…Catch` で囲み、予期せぬ終了を防ぎましょう。
  • キャンセル処理: `CancellationTokenSource` を使うと、ユーザーが「中止」ボタンを押した時に処理を止める実装も可能です。

最後に:プロへの一歩

今回のコードをマスターすれば、あなたの作る業務ツールは、Excelのマクロとは一線を画す「商用レベルの滑らかさ」を手に入れます。

非同期処理は、最初は少し難しく感じるかもしれません。でも、「メインのUIを止めない」という意識を持つだけで、あなたのコードの品質は劇的に向上します。

「ここをクリアすれば、VB.NETの基本はバッチリですよ!」
また次のステップでお会いしましょう。あなたの開発ライフが、もっと快適で楽しいものになりますように。

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