title: Exception, but only on 3rd time - The IAsyncResult object was not returned from the corresponding asynchronous method on this class
body: <p>I have a legacy (2008) Windows service application (using System.ServiceProcess.ServiceBase) that I need to utilize in a slightly different way to how it's working now. At the moment it starts up and creates a TCPLISTENER on a specific port, for a client app to connect to (which it does once) in order to send/receive requests to the listening port. This all works fine. However, the adaptation requires use of a web app to connect to the listener port, then send/rcv as normal but after the receive it must DISCONNECT(*)</p>
  
  <p>(* - if the web app didn't have to disconnect from the listening socket after each test that'd be better, but how I might achieve this is beyond me. Can I keep a TCP connection in session state for re-use?)</p>
  
  <p>Anyway, the adaptation all works fine for the first <strong>TWO</strong> connect/send/rcv/disconnect tests but on the <strong>THIRD</strong> the service throws an ArgumentException in the EndAccept of the Socket class. </p>
  
  <p>I don't understand why it is failing on the 3rd test. </p>
  
  <hr>
  
  <p>Here is the simple test client.</p>
  
  <pre class="lang-vb prettyprint-override"><code>      Public Class ConnectDisconnectTCP
      Inherits System.Web.UI.Page
      Private IP As String = "127.0.0.1"
      Private port As Int32 = 10002
      Private mTCP As System.Net.Sockets.TcpClient
      Private netStrm As NetworkStream
  
      Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
  
      End Sub
  
      Protected Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
          Dim oEnc As New ASCIIEncoding
          Dim ScanText As String = "100000000093001X" + vbLf
          Dim mTCP As System.Net.Sockets.TcpClient
  
          'connect and create a tcpclient
          mTCP = New System.Net.Sockets.TcpClient(IP, port)
          netStrm = mTCP.GetStream()
          netStrm.WriteAsync(oEnc.GetBytes(ScanText.ToString), 0, ScanText.ToString.Length)
  
          If netStrm.CanRead Then
  
              Dim myReadBuffer(1024) As Byte
              Dim myCompleteMessage As StringBuilder = New StringBuilder()
              Dim numberOfBytesRead As Integer = 0
  
              ' Incoming message may be larger than the buffer size.
              Do
                  numberOfBytesRead = netStrm.Read(myReadBuffer, 0, myReadBuffer.Length)
                  myCompleteMessage.AppendFormat("{0}", Encoding.ASCII.GetString(myReadBuffer, 0, numberOfBytesRead))
              Loop While netStrm.DataAvailable
  
          End If
  
         'CLOSE
          netStrm.Close()
          mTCP.Close() 'Disposes this TcpClient instance and requests that the underlying TCP connection be closed.
          mTCP = Nothing
          Label1.Text = "Closed"
      End Sub End Class
  </code></pre>
  
  <hr>
  
  <p>And here is the TCPListener class on the service that does all the work</p>
  
  <pre class="lang-or-tag-here prettyprint-override"><code>   Imports System
      Imports System.IO
      Imports System.Net
      Imports System.Net.Sockets
      Imports System.Threading
      Imports System.Text
  
      Public Class TCPListenerPort
  
      Private currentAsynchResult As IAsyncResult
      Private cState As ClientState
      Private servSock As New Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp)
      Private m_connectionstate As Int32 = 0
      Dim sData As String = String.Empty
  
      'counters
      Public cnt As Int32 = 0
      Public rcvcnt As Int32 = 0
      Public acccnt As Int32 = 0
      Public sndcnt As Int32 = 0
      Public sndcal As Int32 = 0
      Public cncnt As Int32 = 0
  
      'Public Events
      Public Event ConnectionState(ByVal enmState As Int32)
      Public Event DataArrived(ByVal strData As Object)
  
      Public Sub New()
      End Sub
  
      Public Sub New(ByVal dr As DataRow)
  
      End Sub
  
      Protected Overrides Sub Finalize()
          Try
              If Not cState Is Nothing Then
                  cState.ClntSock.Close()
              End If
              If Not servSock Is Nothing Then
                  servSock.Close()
              End If
          Catch ex As Exception
              Throw ex
          Finally
              MyBase.Finalize()
          End Try
      End Sub
  
      Private Class ClientState
  
          Public Const BUFSIZE As Integer = 1024
  
          Public mrcvBuffer As Byte() = New Byte(BUFSIZE - 1) {}
          Public mSendBuffer As Byte() = New Byte(BUFSIZE - 1) {}
  
          Private mclntSock As Socket = Nothing
  
  
          Public Sub New(ByRef clntSock As Socket)
              mclntSock = clntSock
              ReDim mrcvBuffer(BUFSIZE)
              ReDim mSendBuffer(BUFSIZE)
          End Sub
  
          Public ReadOnly Property SckConnected() As Boolean
              Get
                  SckConnected = mclntSock.Connected
              End Get
          End Property
  
          Public ReadOnly Property RcvBuffer() As Byte()
              Get
                  RcvBuffer = mrcvBuffer
              End Get
          End Property
  
          Public ReadOnly Property SendBuffer() As Byte()
              Get
                  SendBuffer = mSendBuffer
              End Get
          End Property
  
          Public ReadOnly Property ClntSock() As Socket
              Get
                  ClntSock = mclntSock
              End Get
          End Property
  
      End Class
  
      Public Sub Connect(ByVal TCPPort As Int32, ByVal Backlog As Int32)
  
  
  
          Try
              cState = New ClientState(servSock)
              cState.ClntSock.Bind(New IPEndPoint(System.Net.IPAddress.Any, TCPPort))
              cState.ClntSock.Listen(100) '5
  
              While True
                  cncnt = cncnt + 1
                  System.Diagnostics.Debug.WriteLine("in connect WHILE " + cncnt.ToString)
                  currentAsynchResult = servSock.BeginAccept(New AsyncCallback(AddressOf AcceptCallback), cState)
                  currentAsynchResult.AsyncWaitHandle.WaitOne()
              End While
  
          Catch __unusedObjectDisposedException1__ As ObjectDisposedException
          Catch e As Exception
          End Try
      End Sub
  
      Private Sub AcceptCallback(ByVal asyncResult As IAsyncResult)
  
  
          Try
  
              acccnt = acccnt + 1
              System.Diagnostics.Debug.WriteLine("AcceptCallback Start" + acccnt.ToString)
  
              'obtain the Socket on which the connection attempt is being made
              Dim servSock As ClientState = asyncResult.AsyncState 'Asyncstate gets a user defined object that qualifies or contains info about an async operation
              Dim clntSock As Socket
  
              clntSock = servSock.ClntSock.EndAccept(asyncResult)
  
              System.Diagnostics.Debug.WriteLine(clntSock.RemoteEndPoint)
  
              Dim cs As New ClientState(clntSock)
              clntSock.BeginReceive(cs.RcvBuffer, 0, cs.RcvBuffer.Length, SocketFlags.None, New AsyncCallback(AddressOf ReceiveCallback), cs)
  
          Catch ar As ArgumentException
  
              '!!!!!Test 3 errors here with
              'The IAsyncResult object was not returned from the corresponding asynchronous method on this class.
  
          Catch ex As Exception
  
          End Try
  
          System.Diagnostics.Debug.WriteLine("AcceptCallback End " + acccnt.ToString)
  
      End Sub
  
      Private Sub ReceiveCallback(ByVal asyncResult As IAsyncResult)
          rcvcnt = rcvcnt + 1
          System.Diagnostics.Debug.WriteLine("ReceiveCallback In " + rcvcnt.ToString)
          Dim cs As ClientState = asyncResult.AsyncState
          Dim AE As New System.Text.ASCIIEncoding
          Dim recvMsgSize As Int32 = 0
          Dim strTmp As String = String.Empty
          Dim strSend As String = String.Empty
  
          Try
  
              recvMsgSize = cs.ClntSock.EndReceive(asyncResult)
              strTmp = Replace(AE.GetString(cs.RcvBuffer), vbNullChar, "")
              If recvMsgSize &gt; 0 Then
                  System.Diagnostics.Debug.WriteLine("ReceiveCallback receiveMsgSize " + recvMsgSize.ToString)
                  If Right(strTmp, 1) = vbLf Or Right(strTmp, 1) = vbCr Then
                      strSend = sData + strTmp
                      strSend = strSend.Replace(vbLf, "")
                      strSend = strSend.Replace(vbCr, "")
                      cState = cs
                      sData = String.Empty
  
                      RaiseEvent DataArrived(strSend)
                  Else
  
                  End If
  
              Else
  
              End If
  
  
          Catch ex As Exception
  
              Throw ex
          End Try
  
          System.Diagnostics.Debug.WriteLine("ReceiveCallback Exit " + rcvcnt.ToString)
  
      End Sub
  
      Public Function SendData(ByVal strData As Object) As Boolean
  
          ' Change the data to a byte array if necessary, then send it via the socket
          Dim oEncoder As New System.Text.ASCIIEncoding
          Dim bytes As Byte()
          Dim Result As IAsyncResult
  
          Try
  
              Select Case strData.GetType().ToString
                  Case "System.String" ' Convert a string to a byte array
                      bytes = oEncoder.GetBytes(strData)
                  Case "System.Byte[]" ' Send a byte array directly
                      bytes = strData
                  Case Else ' And just send anything else as-is
                      bytes = strData
              End Select
  
              sndcnt = sndcnt + 1
              Result = cState.ClntSock.BeginSend(bytes, 0, bytes.Length, SocketFlags.None, New AsyncCallback(AddressOf SendCallback), cState)
              System.Diagnostics.Debug.WriteLine("SendData " + sndcnt + " " + Result.ToString)
  
              Result.AsyncWaitHandle.WaitOne()
  
          Catch ex As Exception
              Throw ex
          End Try
          Return True
  
      End Function
  
      Private Sub SendCallback(ByVal asyncResult As IAsyncResult)
  
          Dim cs As ClientState = asyncResult.AsyncState
          Dim bytesSent As Int32 = 0
  
          Try
              bytesSent = cs.ClntSock.EndSend(asyncResult)
              sndcal = sndcal + 1
  
              cs.ClntSock.BeginReceive(cs.RcvBuffer, 0, cs.RcvBuffer.Length, SocketFlags.None, New AsyncCallback(AddressOf ReceiveCallback), cs)
              System.Diagnostics.Debug.WriteLine("SendCallBack " + sndcal.ToString + " " + bytesSent.ToString)
  
          Catch ex As Exception
              Throw (ex)
          End Try
  
      End Sub
  
  
      End Class
  </code></pre>
  
  <hr>
  
  <p>With .net trace on, plus the code's system diagnostics debug.write, here is a complete log of the TEST1, TEST2, TEST3/CRASH operation. Note the '&lt;-- SCANTEXT RECEIVED' and '&lt;-- RESPONSE RECEIVED' annotations. The 'in connect WHILE 4' annotation shows the arrival of the 3rd request attempt.</p>
  
  <p><code></p>
  
  <pre><code>    [12572] TcpClient#57416410::TcpClient(AddressFamily#2)
      [12572] Socket#61940669::Socket(AddressFamily#2)
      [12572] Exiting Socket#61940669::Socket() 
      [12572] Exiting TcpClient#57416410::TcpClient() 
      [12572] TcpClient#57416410::TcpClient()
      [12572] Exiting TcpClient#57416410::TcpClient() 
      [12572] Socket#15193904::Socket(AddressFamily#2)
      [12572] Exiting Socket#15193904::Socket() 
      [17872] Socket#40528290::Socket(AddressFamily#2)
      [17872] Exiting Socket#40528290::Socket() 
      [17872] Socket#40528290::Bind(0.0.0.0:10002#10002)
      [17872] Exiting Socket#40528290::Bind() 
      [17872] Socket#40528290::Listen(Int32#100)
      [17872] Exiting Socket#40528290::Listen() 
      in connect WHILE 1
      [17872] Socket#40528290::BeginAccept()
      [17872] Exiting Socket#40528290::BeginAccept()  -&gt; AcceptAsyncResult#515737
      The thread '1' (0x6674) has exited with code 0 (0x0).
      The thread '&lt;No Name&gt;' (0x1df8) has exited with code 0 (0x0).
      The thread '&lt;No Name&gt;' (0x5dac) has exited with code 0 (0x0).
      [7984] Socket#49538252::Socket()
      [7984] Exiting Socket#49538252::Socket() 
      in connect WHILE 2
      AcceptCallback Start1
      [17872] Socket#40528290::BeginAccept()
      [7984] Socket#40528290::EndAccept(AcceptAsyncResult#515737)
      [17872] Exiting Socket#40528290::BeginAccept()  -&gt; AcceptAsyncResult#27334100
      System.Net.Sockets Information: 0 : [7984] Socket#49538252 - Accepted connection from 127.0.0.1:63817 to 127.0.0.1:10002.
      [7984] Exiting Socket#40528290::EndAccept()     -&gt; Socket#49538252
      127.0.0.1:63817
      [7984] Socket#49538252::BeginReceive()
      [7984] Exiting Socket#49538252::BeginReceive()  -&gt; OverlappedAsyncResult#62696216
      AcceptCallback End 1
      [22168] Data from Socket#49538252::PostCompletion
      [22168] 00000000 : 32 30 30 30 30 30 30 30-30 30 38 33 30 30 31 58 : 100000000093001X &lt;-- SCANTEXT RECEIVED, TEST1
      [22168] 00000010 : 0A                                              : .
      ReceiveCallback In 1
      [22168] Socket#49538252::EndReceive(OverlappedAsyncResult#62696216)
      [22168] Exiting Socket#49538252::EndReceive()   -&gt; Int32#17
      ReceiveCallback receiveMsgSize 17
      [22168] Socket#49538252::BeginSend()
      [22168] Exiting Socket#49538252::BeginSend()    -&gt; OverlappedAsyncResult#13462887
      A first chance exception of type 'System.FormatException' occurred in Microsoft.VisualBasic.dll
      [19228] Data from Socket#49538252::PostCompletion
      [19228] 00000000 : 07                                              : . &lt;-- RESPONSE RECEIVED, TEST1
      [19228] Socket#49538252::EndSend(OverlappedAsyncResult#13462887)
      [19228] Exiting Socket#49538252::EndSend()  -&gt; Int32#1
      [19228] Socket#49538252::BeginReceive()
      [19228] Exiting Socket#49538252::BeginReceive()     -&gt; OverlappedAsyncResult#25961440
      SendCallBack 1 1
      [7984] Data from Socket#49538252::PostCompletion
      [7984] 00000000 :                                                 : 
      ReceiveCallback In 2
      [7984] Socket#49538252::EndReceive(OverlappedAsyncResult#25961440)
      [7984] Exiting Socket#49538252::EndReceive()    -&gt; Int32#0
      ReceiveCallback Exit 2
      ReceiveCallback Exit 2
      [22168] Socket#31352595::Socket()
      [22168] Exiting Socket#31352595::Socket() 
      AcceptCallback Start2
      in connect WHILE 3
      [17872] Socket#40528290::BeginAccept()
      [22168] Socket#40528290::EndAccept(AcceptAsyncResult#27334100)
      [17872] Exiting Socket#40528290::BeginAccept()  -&gt; AcceptAsyncResult#39421196
      System.Net.Sockets Information: 0 : [22168] Socket#31352595 - Accepted connection from 127.0.0.1:63820 to 127.0.0.1:10002.
      [22168] Exiting Socket#40528290::EndAccept()    -&gt; Socket#31352595
      127.0.0.1:63820
      [22168] Socket#31352595::BeginReceive()
      [22168] Exiting Socket#31352595::BeginReceive()     -&gt; OverlappedAsyncResult#28002689
      AcceptCallback End 2
      [7984] Data from Socket#31352595::PostCompletion
      [7984] 00000000 : 32 30 30 30 30 30 30 30-30 30 38 33 30 30 31 58 : 100000000093001X &lt;-- SCANTEXT RECEIVED, TEST2
      [7984] 00000010 : 0A                                              : .
      ReceiveCallback In 3
      [7984] Socket#31352595::EndReceive(OverlappedAsyncResult#28002689)
      [7984] Exiting Socket#31352595::EndReceive()    -&gt; Int32#17
      ReceiveCallback receiveMsgSize 17
      [7984] Socket#31352595::BeginSend()
      [7984] Exiting Socket#31352595::BeginSend()     -&gt; OverlappedAsyncResult#31071611
      [22168] Data from Socket#31352595::PostCompletion
      A first chance exception of type 'System.FormatException' occurred in Microsoft.VisualBasic.dll
      [22168] 00000000 : 07                                              : . &lt;-- RESULT RECEIVED, TEST2
      [22168] Socket#31352595::EndSend(OverlappedAsyncResult#31071611)
      [22168] Exiting Socket#31352595::EndSend()  -&gt; Int32#1
      [22168] Socket#31352595::BeginReceive()
      [22168] Exiting Socket#31352595::BeginReceive()     -&gt; OverlappedAsyncResult#51673536
      SendCallBack 2 1
      [4640] Data from Socket#31352595::PostCompletion
      [4640] 00000000 :                                                 : 
      ReceiveCallback Exit 3
      The thread '&lt;No Name&gt;' (0x4b1c) has exited with code 0 (0x0).
      ReceiveCallback In 4
      [4640] Socket#31352595::EndReceive(OverlappedAsyncResult#51673536)
      [4640] Exiting Socket#31352595::EndReceive()    -&gt; Int32#0
      ReceiveCallback Exit 4
      [4640] Socket#37088038::Socket()
      [4640] Exiting Socket#37088038::Socket() 
      AcceptCallback Start3
      [4640] Socket#49538252::EndAccept(AcceptAsyncResult#39421196)
      in connect WHILE 4
      [17872] Socket#40528290::BeginAccept()
      [17872] Exiting Socket#40528290::BeginAccept()  -&gt; AcceptAsyncResult#8948635
      //ERROR THROWN HERE
      AcceptCallback End 3
  </code></pre>
  
  <p></code></p>
  
  <hr>
  
  <p><strong>Monitoring with netstat</strong></p>
  
  <p>When the service is started, this appears, indicating the service is listening on port 10002</p>
  
  <pre><code>    TCP    0.0.0.0:10002 LON-WKS-ZER01:0      LISTENING
  </code></pre>
  
  <p>On the 1st and 2nd scans (ie successful) everything works fine. The test web app connects, sends 'scantext', various callback delegates are fired, and we get a good reply. </p>
  
  <p>Netstat during the 1st test, after the connection is made :</p>
  
  <pre><code>    TCP    0.0.0.0:10002          LON-WKS-ZER01:0      LISTENING
      TCP    127.0.0.1:10002        apps:59574             ESTABLISHED
      TCP    127.0.0.1:59574        apps:10002             ESTABLISHED
  </code></pre>
  
  <p>(then scan #1 is completed)</p>
  
  <p>When testApp mTCP.Close() called, the status changes to CLOSE_WAIT and FIN_WAIT_2</p>
  
  <pre><code>   TCP    0.0.0.0:10002          LON-WKS-ZER01:0      LISTENING
     TCP    127.0.0.1:10002        apps:59574             CLOSE_WAIT
     TCP    127.0.0.1:59574        apps:10002             FIN_WAIT_2
  </code></pre>
  
  <p>A few mins later, the CLOSE and FIN connections disappear but still have the LISTENER</p>
  
  <pre><code> TCP    0.0.0.0:10002          LON-WKS-ZER01:0      LISTENING
  </code></pre>
  
  <p>Next, send scan#2, it repeats the sequence as above, with a successful result.</p>
  
  <p>On the third scan, when it attempts to make a new connection, the exception is thrown in AcceptCallback on this line :</p>
  
  <pre><code>clntSock = servSock.ClntSock.EndAccept(asyncResult)
  </code></pre>
  
  <p>Specifically, it's an ArgumentException, 'asyncResult was not created by a call to BeginAccept' (see <a href="https://msdn.microsoft.com/en-us/library/zdee4kd7(v=vs.110).aspx" rel="nofollow noreferrer">EndAccept</a>)</p>
  
  <p>So, for reasons I can't quite fathom, the IASyncResult of the 3rd test is causing the EndAccept method to throw an ArgumentException.</p>
  
  <p>To summarise the bug - the Connect call's BeginAccept sets up a delegate for AcceptCallback and passes an IASyncResult. The AcceptCallBacks EndAccept throws an ArgumentException</p>
  
  <p>I realise the way things are being done are not very up to date and we'd be better off with something else, but with one thing and another (time, resource) I need to try and make the slight adaptation work. But I don't understand why (existing client app) CONNECT, scan,scan,scan,scan etc works, but (web app) CONNECT,scan,DISCONNECT, CONNECT, scan, DISCONNECT fails on the THIRD scan's CONNECT</p>
  
  <p>Thanks in advance for any suggestions. </p>