我有时会收到此错误:
使用此SocketAsyncEventArgs实例正在进行异步套接字操作。
...当我尝试拨打SocketServiceEventArgs.SetBuffer()
我意识到这是因为一个实例只能执行一个操作而且必须在使用中。但是我再次调用它是因为在客户端之前的超时之后,我希望尝试重新发送请求。我不想关闭这个套接字并使用新的套接字,因为那时连接将被客户端破坏。
但是,我需要做的是在执行此操作之前检查是否有其他操作正在进行中,如果是,请终止它,以便我可以再次发送。
我用来发送的代码是
saeaCommunicationObject.AcceptSocket.SendAsync(saeaCommunicationObject)
但更有可能正在进行的是接收
saeaCommunicationObject.AcceptSocket.ReceiveAsync(saeaCommunicationObject))
(saeaCommunicationObject
是SocketAsyncEventArgs
)。
在研究中,我遇到过
AcceptSocket.EndReceive(IAsyncResult asyncResult)
但我不确定这是否正确,而且我也不知道在哪里获得asyncResult(所以如果这是正确的,我的问题是,这应该来自哪里?)
那么我该怎么做才能检查它是否在进行中(如果是,则终止它)?
修改
我看过一个地方建议(但不建议)使用P / Invoke使用CancelIoEx()
- 但是我无法解决这个问题,而且这方面的文档很少。
[DllImport("kernel32.dll", CallingConvention = CallingConvention.Cdecl)]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool CancelIoEx(IntPtr hFile);
private void CancelReceive() {
bool result = CancelIoEx(saeaCommunicationObject.AcceptSocket.Handle)
// etc.
}
我得到result
= false
。我还尝试了CancelIo()
,当我得到result
= true
时,当我尝试调用SetBuffer()
时会抛出相同的异常。
TL; DR
一旦ReceiveAsync()
被调用,所以现在套接字正在等待输入以触发Completed
事件,如何取消此请求?
答案 0 :(得分:1)
来自MSDN:
如果I / O操作处于挂起状态,则返回true。操作完成后,将引发e参数上的SocketAsyncEventArgs.Completed事件。 如果I / O操作同步完成,则返回false。在这种情况下,e参数上的SocketAsyncEventArgs.Completed事件不会被引发,并且在方法调用返回后立即检查作为参数传递的e对象以检索操作的结果。
因此,您应该检查ReceiveAsync
电话的返回值。如果其true
订阅SocketAsyncEventArgs.Completed
事件。如果错误,请立即检查SocketAsyncEventArgs
以验证结果。
答案 1 :(得分:0)
不是特定问题的答案,但我目前的解决方法是检查AcceptSocket.BytesAvailable
值并等待它为>在致电ReceiveAsync()
之前0。这样,如果我需要先调用SendAsync()
,它就会被中断。
我认为这样效率会有所降低,而且我不确定它会有多大的可扩展性,考虑到可能有多达50个客户端同时连接 - 但它似乎让我超过这个驼峰现在。