TcpClient.BeginConnect/TcpClient.EndConnect
コンボでサーバーに接続しようとしています。しかし、いくつかのことは、必要なときには機能しません。ソケットが閉じているときにTcpClient.EndConnectがNullReferenceExceptionをスローする
次のようなシナリオがある:TcpClient.BeginConnect
- コール(テスト目的のために)意図的にオフラインになっている - 従ってない接続が行われないことができます。
- Iは
TcpClient
接続コールバックメソッドが所定IAsyncResult
NullReferenceException
がEndConnect
で発生するとTcpClient.EndConnect
方法にIAsyncResult
- コール(を与える起こる(
client.Close()
はcloses the socket which in turn stops the async operationプロセスで呼び出される)アプリケーションを閉じます?) - 最後のフォーム(ウィンドウ)が閉じられたので、アプリは終了する必要がありますが、少なくとも、
BeginConnect
の操作が完了するまで(これは、コールバックが既に呼び出されているので、奇妙です)。ここでは何が起こる
はNullReferenceException
がキャッチされていることです。上の写真からわかるように、client
でもar
もnull
です。問題は、MSDN documentation for the EndConnectにこの例外がスローされた場合は言及していないことです。
基本的に、私は何が起こっているのか分かりません。問題は、(接続操作がまだタイムアウトを待っているかのように)アプリケーションが終了するのを待たなければならないことです。 サーバがオンラインになっている場合、サーバは正しく接続され、接続が切断されます。。
この文脈でNullReferenceException
は何を意味するのでしょうか?どのように接続を確立することができない場合に閉じるアプリケーションをブロックする操作BeginConnect
を回避するには?
その他の注意事項(コメントで要求):ここで
は、クライアントを作成するためのコードである(クライアントがメンバ変数である。また、
public void Connect()
{
try
{
lock (connectionAccess)
{
if (State.IsConnectable())
{
// Create a client
client = new TcpClient();
client.LingerState = new LingerOption(false, 0);
client.NoDelay = true;
State = CommunicationState.Connecting;
client.BeginConnect(address, port, onTcpClientConnectionEstablished, null);
}
else
{
// Ignore connecting request if a connection is in a state that is not connectable
}
}
}
catch
{
Close(true);
}
}
Closeメソッド:
public void Close(bool causedByError)
{
lock (connectionAccess)
{
// Close the stream
if (clientStream != null)
clientStream.Close();
// Close the gateway
if (client != null)
client.Close();
// Empty the mailboxes
incomingMailbox.Clear();
outgoingMailbox.Clear();
State = causedByError ? CommunicationState.CommunicationError : CommunicationState.Disconnected;
}
}
InnerExceptionは、何がNULLであったかについての詳細情報を提供しますか? – Tremmors
@Tremmors Nope。 InnerExceptionはnullです。 StackTraceのヘルプもありません(onTcpClientConnectionEstablished> EndConnect)。 : –
はい、明らかにフレームワークのバグです.TcpClientがEndConnect()が呼び出される前に閉じられている場合は、ObjectDisposedExceptionをスローするはずですが、NullReferenceExceptionを最初の1,2回取得したように見えて、ObjectDisposedExceptionをスローします。私はあなたが単にObjectDisposedException(つまり、 "接続のタイムアウト/失敗/あなたがClose()"と呼んだその他の理由)と同じように扱うことをお勧めします。しかし、リソースが漏れているかどうかはわかりませんここではEndConnect()が完了していないので、おそらくGCが処理できないものはありません:) – Tom