C#のBiginConnectメソッドのコールバック関数で例外「破棄したオブジェクトにアクセスできません」が発生した原因

アリスです。

デバイスとの通信処理をC#で行うには色々とやり方があります。

BeginConnectメソッドを使用して、デバイスとの通信を確立する際に発生した、例外の原因を書きます。

スポンサーリンク
スポンサーリンク

BeginConnectメソッド

BeginConnecメソッドを使うプログラミングは、正直古い手法です。

.Net Frameworkのバージョン2で追加されたライブラリだからです。

今から8年前でしょうか。

現在の.Net Frameworkのバージョンは4.7ですし。

 

確かに古い方法ではあるのですが、BeginConnectメソッドが使われているソフトウェアは多いです。

今回私が機能追加したソフトウェアでもBeginConnectメソッドを使用して、TCP/IPの通信プログラムが書かれていました。

 

新しいデバイスに対応させるという内容の機能追加です。

作成したプログラムで様々な検証を行っていたところ、通信中にLANの接続が切れたときの確認で例外が発生しました。

スポンサーリンク

プログラムコード

下記がプログラムコードの例外が発生した箇所です。

// ソケット作成
Socket client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

// 非同期での接続処理
client.BeginConnect(endpoint, new AsyncCallback(ConnectedCallback), client);


// 接続完了時のコールバック
private void ConnectedCallback(IAsyncResult ar)
{
	try
	{
		Socket client = (Socket)ar.AsyncState;
		client.EndConnect(ar); //この行の実行時に例外発生
	}
	catch (ObjectDisposedException ex)
	{
		// 例外(破棄したオブジェクトにアクセスできません)
	}
}

 

デバイスとの通信するにあたり、最初に通信の接続を、非同期で行います。
するとTcp接続が成功/失敗したかどうかにかかわらず、接続完了のコールバック(ConnectedCallback)が呼ばれます。

接続されたか失敗したかは、コールバックメソッドのclient変数の「Connected」プロパティを調べる必要があります。
falseなら失敗ということです。

 

通信中にLANの接続を切り、そのあと再接続しようとすると、client.EndConnect(ar)の行で、「破棄したオブジェクトにアクセスできません」という例外が発生しました。

スポンサーリンク

例外の原因

原因は通信相手のデバイスがマンツーマンでの通信しか許可していなかったためです。
つまり、通信中にLANを断線すると、断線前の通信状態がクリアされず、他からの新たな接続を受け付けなかったのです。
ということで、こちらのプログラムに問題はありませんでした。(デバイス側の問題でした)

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