次の方法で共有


Coding4Fun: 持ち運ぶ - 第 2 部

持ち運ぶ - 第 2 部

Arian Kulp

May 19, 2006
日本語版最終更新日 2006 年 8 月 9 日

はじめに

前回の記事では、.NET のモビリティについて、特に電源の認識に重点を置いて説明しました。アプリケーションは電源を認識すると、バッテリと AC 電源のどちらで実行されているかや、バッテリの充電レベル、充電の状態、充電残量がなくなるまでの推定時間を把握してうまく調整できます。まだご覧になっていない場合は、「持ち運ぶ - 第 1 部」をご覧ください。

この記事でも引き続きモビリティについて説明しますが、今回はネットワークの認識に重点を置いて説明します。アプリケーションはネットワークの状態を認識すると、状況に応じてファイル転送を停止および再開したり、オンライン モードとオフライン モードを切り替えることができます。また、ネットワーク障害によって生成されるエラー メッセージの数が減少します。優れたアプリケーションはその動作環境に適合する必要がありますが、適切なツールがない場合、開発者は低レベルのシステム呼び出しに戻すか、あまりスマートでない解決策に頼るしかありません。

この記事のコードはすべて C# と Visual Basic で記述されており、このページの上部にあるリンクからダウンロードできます。このコードは主に説明を目的としたものですが、すべて機能しますので、独自のプロジェクトでお使いになることも可能です。サンプル プログラム ファイル内では実際のコメント行は英語で書かれていますが、この記事内では説明目的で日本語で書かれています。 このコラムでは、Microsoft Visual Basic Express Edition または Microsoft Visual C# Express Edition のコピーが必要です。どちらも無償でダウンロードできます。https://www.microsoft.com/japan/msdn/vstudio/express/ から、これらのコピーのいずれか (および他の Visual Studio Express Edition) をダウンロードできます。ネットワークの認識に関するモビリティの機能を正確にテストするには、ネットワーク アダプタを無効にするか、ネットワーク ケーブルを取り外すか、ワイヤレス カードを取り外す必要があります。

接続の操作

ネットワーク接続は、多くのアプリケーション開発で考慮されるシステム機能です。ファイルの転送や Web サービスへの接続などのネットワーク接続コードに try/catch を使用することはよくあります。しかし、ネットワーク接続が確立された後にその接続が切断されたらどうなるでしょうか。この状況に適切に対処できることは重要です。また、実際のエラーが発生する前にアプリケーションの動作を変更できれば、さらに効果的です。たとえば、接続を確立できないときに例外に頼るのではなく、オフラインのときは単に接続オプションを完全に無効にするコードを記述できます。

オンラインであるかオフラインであるかを示すインジケータを簡単に追加するには、特定の接続を定期的に試行し、その接続が成功したかどうかを示すブール値のフラグをコード内に設定します。これにより、接続に依存するその他のコード セクションは、ネットワークを使用する前に、このフラグが true に設定されているかどうかを確認できます。このコードの例を次に示します。

  
    bool onlineFlag =false;
 
 ...
 
// タイマで数秒ごとに実行します
publicvoid VerifyConnection()
 {
try
     {
// ここで接続を試行します
 onlineFlag =true;
     }
catch
     {
 onlineFlag =false;
     }
 }

この方法にはいくつかの問題があります。そのうちの 1 つは、フラグの確認をバックグラウンド スレッド上または Timer オブジェクトから実行することにより、不要なシステム オーバーヘッドが発生し、作成したアプリケーションやシステムで実行されているその他のアプリケーションに影響を与える可能性があるということです。他には、接続フラグのためだけに定期的にアクセスするのでは、サービスがもったいないという問題もあります。また、この方法では流れを制御するときに例外処理を使用します。try ブロックだけではそれほどオーバーヘッドは発生しませんが、例外処理では大量のオーバーヘッドが発生します。接続できない場合は多くの例外処理が必要になります。さらに、この方法では、ローカル コンピュータの接続が切断されているのか、リモート サービスの接続が切断されているのかを判断できません。

さいわい .NET Framework 2.0 を使用すると、システムにネットワーク接続が存在するかどうかをいくつかの方法で確認できます。新しい System.Net.NetworkInformation 名前空間では、接続状態などの確認に役立つ情報が提供されます。MSDN のドキュメントには、「System.Net.NetworkInformation 名前空間は、ネットワーク トラフィック データ、ネットワーク アドレス情報、ローカル コンピュータのアドレス変更通知へのアクセスを提供します。この名前空間には、Ping ユーティリティを実装するクラスも含まれます。Ping および関連するクラスを使用すると、特定のコンピュータにネットワーク経由でアクセスできるかどうかをチェックできます。」と記載されています。この情報を使用すると、接続が確立されているかどうか、最高速度、特定のアダプタに関する情報、リモート ホストにアクセスできるかどうかを確認できます。

サンプル アプリケーションでは、この名前空間のクラスから収集したいくつかの情報を表示します。図 1 のように、右側には [Network] セクションがあります。このインターフェイスの大部分については、前回の記事に記載されています。ただし、[Network] セクションには若干の変更を加えたため、この記事で紹介するコードをご利用ください。このアプリケーションでは、全体的なネットワークの可用性、ローカル IP アドレス、インターフェイスの最高速度、google.com にアクセスできるかどうか、および最も有効なインターフェイスを確認できます。

図 1: インターネット接続が有効である場合

最も基本的な機能は、ネットワーク接続が利用可能であるかどうかの確認です。この操作を簡単に行うための方法が 2 つあります。1 つ目は、1 つのメソッドを確認する方法です。NetworkInformation 名前空間の NetworkInterface オブジェクトには、ネットワーク アダプタを列挙する静的メソッドと、オンライン状態を確認する静的メソッドが用意されています。

GetIsNetworkAvailable メソッドは、その名のとおり、ネットワークに接続されているネットワーク アダプタがシステムに存在するかどうかを示す true または false を返すだけです。次のコード スニペットを使用すると、システムがオンラインであるかどうかを最も簡単に確認できます。

  NetworkInterface.GetIsNetworkAvailable()

これは簡単な方法ですが、それほど多くの状況で役立つわけではありません。このメソッドをタイマで数秒ごとに確認する必要がある場合、例外処理の方法ではあまりメリットを得ることができませんでした (これはまだ改善途中ですが)。状態をこちらから確認するのではなく、オンラインとオフラインが切り替わったときに対処できるのが理想的です。さいわいにもこの動作は実現できます。

同じく System.Net.NetworkInformation 名前空間の NetworkChange オブジェクトは、次の 2 つの静的イベントを公開しています。

  1. NetworkAddressChanged

  2. NetworkAvailabilityChanged

予想していたかもしれませんが、ここで使用するのは NetworkAvailabilityChanged イベントです。イベント ハンドラを追加すると、システムがオンラインまたはオフラインになったときに、必ず通知を受け取ることができます。通知を受け取ったら、このイベントの IsAvailable プロパティで状態を確認できます。これで、ステータス バーを更新したり、データ転送を中断したり、あるいは、状態が変化したことを説明することができます。

図 2: インターネット接続が無効である場合 (ワイヤレス接続が無効である場合)

注意すべき重要なことがいくつかあります。まず、ネットワーク接続を利用できても、インターネット接続は "オンライン" ではない場合があります。これは重要な違いです。ネットワーク接続は、単にローカル ネットワークへの接続を指しています。イントラネット アプリケーションを (社内などで) 使用するのであれば、ネットワーク接続が利用できれば問題ありません。インターネット接続を確認する必要がある場合は、追加の手順を行う必要があります。

このアプリケーションでは、利用できるネットワークが存在するという報告を受けたときに必ずホスト (google.com) への ping を実行するというサポートを追加しました。"ping" とは、別のコンピュータに信号を送信し、応答を待機してそのコンピュータにアクセスできるかどうかを確認する操作のことです。この用語は、潜水艦とレーダーのアクティブ ソナー音 (ping) を思い起こさせますね。この記事の前半にも記載しましたが、ping を送信すると Web サイトへの不要なトラフィックが発生するため、注意して使用する必要があります。他にも、データベース サーバーが動作しているかどうかを確認する場合などに、ホストに対して ping を実行します。

ホストに対する ping の実行方法は 2 つあります。1 つ目は簡単です。単に System.Net.NetworkInformation.Ping オブジェクトを作成し、ホスト名で Send メソッドを呼び出します。返される PingReply オブジェクトにより、ホストが応答したかどうか、およびそのラウンド トリップ時間を確認できます。このメソッドを使用する場合の問題点は、アプリケーションの遅延を引き起こすことです。メソッドの呼び出し方によっては、呼び出すたびにユーザー インターフェイスがロックされます。

2 つ目は、非同期に ping を実行するという方法です。メソッドを非同期に呼び出すと、異なるスレッドで操作が発生します。これによりメイン スレッドが解放されるため、応答性を維持できます。次の CheckHostReachable メソッドではホスト名を渡しますが、すぐに値が返されます。ping が実際に完了すると、p_PingCompleted イベント ハンドラが呼び出されます。複数のスレッドにまたがるユーザー インターフェイスの呼び出しが発生しないことを (InvokeRequired プロパティで) 確認したら、それに応じてチェック ボックスを更新できます。同期を取る場合よりもやや複雑ですが、ユーザーの操作性は向上します。

  
    private PingCompletedEventHandler pingHandler;
 
 ...
 
privatevoid CheckHostReachable(string host)
 {
try
     {
 System.Net.NetworkInformation.Ping p =new Ping();
 p.PingCompleted += pingHandler;
 hostReachableCheckBox.CheckState = CheckState.Indeterminate;
 p.SendAsync(host, 20000,null);
     }
catch
     {
 hostReachableCheckBox.Checked =false;
     }
 }
 
void p_PingCompleted(object sender, PingCompletedEventArgs e)
 {
// UI と同じスレッドであるかどうかを確認します
if (this.InvokeRequired)
     {
 Invoke(pingHandler, sender, e);
return;
     }
 
 hostReachableCheckBox.CheckState = 
 (e.Error ==null && e.Reply.Status == IPStatus.Success)?CheckState.Checked:CheckState.Unchecked;
 }

残りのコードも確認してみてください。ネットワーク アダプタを列挙し、有効なネットワーク アダプタの状態、種類、名前などの関心のある情報を収集する方法もわかります。これらのメソッドは情報のループ、書式設定、および表示によって多少長くなっていますが、実際はそれほど複雑ではありません。

今後のステップ

ネットワーク アダプタとネットワーク接続に関する情報を確認する方法がわかったら、アプリケーションに組み込む方法を調べてみてください。接続が失敗しても、もうエラーは発生しません (ユーザーがオンラインであることが既にわかっている場合は除きます)。その状況に応じた速度を利用できます。

まとめ

バッテリと電源に関する前回と今回の記事を活用すれば、問題なくアプリケーションをモバイル化できるはずです。この情報を最大限に活用して、ユーザーに適切なフィードバックを提供しましょう。また利用できる情報はすべて利用するようにしましょう。

ページ上部からサンプル コードをダウンロードし、https://www.microsoft.com/japan/msdn/vstudio/express/ から Visual Basic Express または Visual C# Express のコピーをダウンロードして、以前よりも優れたコードを記述してください。アプリケーションにモビリティ機能を追加すると、アプリケーションが移植可能になり、これまでよりも本格的なものにできます。

Arian Kulp は中西部在住のフリーのソフトウェア開発者です。彼は小学校 5 年生のとき以来、次々に異なるプラットフォームでコーディングを行ってきました。最近では .NET Framework に熱中しています。彼の Web サイトは、http://www.ariankulp.com/default.aspx (英語) からご覧になれます。

top of page Top of Page