我正在尝试使用TcpClient.BeginConnect / TcpClient.EndConnect
组合连接到我的服务器。但是,有些事情不能正常运作。
方案如下:
TcpClient.BeginConnect
client.Close()
TcpClient
连接回调方法正在执行IAsyncResult
TcpClient.EndConnect
IAsyncResult
方法
NullReferenceException
发生在EndConnect
(?)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;
}
}
答案 0 :(得分:1)
NullReferenceException
可能是由于TcpClient.Client
为空。
如果您要关注TcpClient.BeginConnect
TcpClient
并将 private void onConnEst(IAsyncResult ar)
{
try
{
TcpClient client = (TcpClient)ar.AsyncState;
if(client!=null && client.Client!=null)
{
client.EndConnect(ar);
}
}
catch(Exception ex){...}
}
对象作为状态对象传递:
Close()
这应该处理在回调之前调用{{1}}的情况。
回到你的问题 - 应用程序最终关闭需要多长时间?
答案 1 :(得分:1)
这显然是TcpClient类中的一个错误。我也面对过它。 TcpClient.Dispose可以将Client字段设置为null,但EndConnect不期望这样。
答案 2 :(得分:0)
我遇到了类似的错误,最后使用了这段代码。我不确定它是否适用于IASyncResult接口,但可能有类似的方法来运行此检查。我注意到你的ar.AsyncState == null,所以也许尝试从那里开始,即正确连接时它是否为null?
private void connConnectCompleted(AsyncCompletedEventArgs e)
{
if (e.Error != null)
{
// Something didn't work...abort captain
CloseSocket();
Console.WriteLine(this.GetType().ToString() + @":Error connecting socket:" + e.Error.Message);
return;
}
// Do stuff with your connection
}
编辑:对不起,我没有意识到我没有发布生成我的AsyncCompletedEventArgs的内容,这与你正在做的事情有关。您将看到我想知道ar.AsyncState为空的原因。
private void OnConnect(IAsyncResult asyncResult)
{
if (OnConnectCompleted == null) return; // Check whether something is using this wrapper
AsyncCompletedEventArgs args;
try
{
Socket outSocket = (Socket) asyncResult.AsyncState;
// Complete connection
outSocket.EndConnect(asyncResult);
args = new AsyncCompletedEventArgs(null);
OnConnectCompleted(this, args);
}
catch (Exception e)
{
args = new AsyncCompletedEventArgs(e.Message);
OnConnectCompleted(this, args);
}
}
答案 3 :(得分:0)
这是a know bug。
您应该收到'ObjectDisposedException'而不是'NullReferenceException'。