こんにちは。現場の最前線でコードと格闘し、システムという生き物を安定させることに命を懸けているエンジニアです。
「ネットが切れたからデータが消えた」。こんな悲劇、業務アプリケーションの世界では絶対に許されません。今日は、VB.NETを使って、ネットワークの気まぐれに左右されない「不屈の業務アプリ」を作るための極意を伝授します。
初心者の方も安心してください。まずは「イベント駆動」の概念を理解し、一歩ずつ堅牢な設計へ登り詰めましょう。
—
1. なぜ「NetworkChange」を使うのか?
Windows Formsアプリにおいて、ネットワークの状態を監視する最もスマートな方法は、`.NET Framework`に標準搭載されている `System.Net.NetworkInformation.NetworkChange` クラスを利用することです。
これは「ポーリング(短い間隔で何度も確認する)」のような非効率な手法ではなく、OSがネットワークの変化を検知した瞬間に通知を飛ばしてくれる「イベント駆動型」の仕組みです。CPUに負荷をかけず、極めて軽量に動作します。
2. 実装の設計思想:オフライン対応の3原則
堅牢なアプリを作るためには、以下の3つを心に刻んでください。
1. 即時検知: `NetworkChange.NetworkAvailabilityChanged` で切断を即座にUIへ反映する。
2. 局所的退避: 送信失敗時は即座にローカルDB(SQLite)へ「未送信キュー」として保存する。
3. 自動復旧: ネットワーク復帰を検知したら、バックグラウンドで未送信データを自動再送する。
—
3. 実践:ネットワーク監視の実装コード
では、実際のコードを見ていきましょう。このコードはフォームが読み込まれた時に監視を開始し、状態が変わった時にイベントを発火させます。
Imports System.Net.NetworkInformation
Public Class MainForm
Private Sub MainForm_Load(sender As Object, e As EventArgs) Handles MyBase.Load
‘ ネットワーク状態の変化を監視するイベントハンドラを登録
AddHandler NetworkChange.NetworkAvailabilityChanged, AddressOf OnNetworkChanged
End Sub
‘ ネットワーク状態が変わった時に自動的に呼び出されるメソッド
Private Sub OnNetworkChanged(sender As Object, e As NetworkAvailabilityEventArgs)
‘ 【重要】イベントは別スレッドで発生するため、UI操作にはInvokeが必要
Me.Invoke(Sub()
If e.IsAvailable Then
lblStatus.Text = “オンライン: 復旧しました。再送を開始します…”
‘ ここでSQLiteから未送信データを読み込み再送する処理を呼ぶ
TryResendData()
Else
lblStatus.Text = “オフライン: ネットワーク切断中。データはローカルに保存されます。”
End If
End Sub)
End Sub
Private Sub TryResendData()
‘ SQLiteからデータを読み込み、サーバーへ送るロジックをここに記述
‘ 例: Dim queue = SqliteHelper.GetPendingData()
End Sub
‘ フォーム終了時は必ずイベントを解除すること(メモリリーク防止!)
Private Sub MainForm_FormClosing(sender As Object, e As FormClosingEventArgs) Handles MyBase.FormClosing
RemoveHandler NetworkChange.NetworkAvailabilityChanged, AddressOf OnNetworkChanged
End Sub
End Class
—
4. 現場で「必ず」陥る落とし穴と対策
① UIスレッドの壁
VB.NETの初心者の方が最もハマるのが、「別スレッドからUIを操作しようとして落ちる」問題です。`NetworkChange`のイベントは、メインのUIスレッドとは異なる場所で動きます。必ず上記のコードのように `Me.Invoke(…)` を介してUIを更新してください。これを知っているだけで、デバッグの時間は半分になります。
② メモリリーク(後始末の徹底)
`AddHandler` でイベントを購読したら、`FormClosing` や `Dispose` で必ず `RemoveHandler` を行いましょう。これを忘れると、フォームを閉じても裏で監視が残り続け、メモリを食いつぶす「ゾンビ状態」になります。
③ なぜ SQLite なのか?
なぜローカルのファイルやテキストではなく SQLite なのか。それはトランザクション(整合性)が担保できるからです。「送信したはずのデータが消えた」という事態を避けるには、書き込み完了まで確実にデータを守れる SQLite が最も安全な選択肢だからです。
—
最後に:エンジニアとしてのマインドセット
「ネットワークは切れるのが当たり前」。
そう考えて設計するエンジニアと、「繋がっているはずだ」と信じてコードを書くエンジニアでは、作るシステムの寿命が全く違います。
今回紹介した `NetworkChange` は、あなたのアプリを「たまに落ちるツール」から「信頼できる業務システム」へと引き上げるための第一歩です。
まずはこのコードをコピーして、ご自身の環境で試してみてください。ネットワークケーブルを抜いた瞬間にUIが変わる感動を味わえたなら、あなたはもう、ワンランク上のエンジニアの入り口に立っていますよ。
何か詰まったら、いつでも聞いてください。応援しています。
