当socket关闭时,TcpClient.EndConnect抛出NullReferenceException

Kor*_*tak 5 c# sockets connection asynchronous tcpclient

我正在尝试使用TcpClient.BeginConnect / TcpClient.EndConnect组合连接到我的服务器.但是,有些东西不能正常工作.

方案如下:

  • 打电话给 TcpClient.BeginConnect
  • 服务器故意脱机(用于测试目的) - 因此无法建立连接.
  • 我关闭应用程序(client.Close()关闭套接字的过程中调用,然后停止异步操作)
  • TcpClient连接回调方法发生了IAsyncResult
  • TcpClient.EndConnect用给定的方法调用方法IAsyncResult
  • NullReferenceException发生在EndConnect()
  • 由于最后一个表单(窗口)已关闭,应用程序应该退出 - 但它不会,至少在BeginConnect操作完成之前(这很奇怪,因为已经调用了回调).

例外

这里发生的事情NullReferenceException就是抓住了.从上图中可以看出,既不是client也不arnull.问题是EndConnectMSDN文档没有提到抛出此异常的情况.

所以基本上,我不知道发生了什么.问题是我被迫等待应用程序关闭(好像连接操作仍然等待超时).如果服务器在线,它连接和断开就好了.

是什么 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);
    }
}
Run Code Online (Sandbox Code Playgroud)

还有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;
    }
}
Run Code Online (Sandbox Code Playgroud)

the*_*fly 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
}
Run Code Online (Sandbox Code Playgroud)

编辑:抱歉,我没有意识到我没有发布生成我的 AsyncCompletedEventArgs 的内容,这与您正在做的事情更相关。您会明白为什么我想知道 ar.AsyncState 为 null 的原因。

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);
    }
}
Run Code Online (Sandbox Code Playgroud)