2017-06-09 29 views
2

私は時々、このエラーが発生します:SocketAsyncEventArgs - 進行中のソケット操作を検出して終了する方法?

を非同期ソケット操作は、このSocketAsyncEventArgsインスタンスを使用して、すでに進行中です。

...私はインスタンスは1つの操作のみを行うことができ、それが使用中でなければならないため、これは実現 SocketServiceEventArgs.SetBuffer()

を呼び出そう。しかし、クライアント側からの以前のタイムアウト後に、要求を再送しようとしているため、私は再度呼び出しています。このソケットを閉じて新しいものを使用することは望ましくありません。クライアントとの接続が切断されるからです。

しかし、これを行う前に別の操作が既に進行中であるかどうかを確認し、もしそうなら、終了して、再度送信できるようにする必要があります。

私が送信するために使用していたコードは

saeaCommunicationObject.AcceptSocket.SendAsync(saeaCommunicationObject)

ですが、どのような進行中である可能性が高いのは、(saeaCommunicationObjectSocketAsyncEventArgsある)

saeaCommunicationObject.AcceptSocket.ReceiveAsync(saeaCommunicationObject))

である受信です。研究では

、私の質問に、私は

AcceptSocket.EndReceive(IAsyncResult asyncResult)

に遭遇してきたが、私はこれが正しいかどうかはわからない、とも私はどこasyncResultを得るには考えている(ので、これが正しいかどうかこれはどこから来たと思われますか?)

それでは、進行中かどうかを確認するにはどうしたらいいですか?

編集私が見

場所の一つが示唆(ただしお勧めしませんでした)P /呼び出しを使用して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. 
} 

私は= falseresultを取得します。私もCancelIo()を試しましたが、result = trueを取得していますが、SetBuffer()を呼び出すと同じ例外がスローされます。

TL; DR

ReceiveAsync()一度はと呼ばれ、私はこの要求をキャンセルしますどのように今のソケットは、Completedイベントを発生させるために、入力を待っていますか? MSDNから

答えて

1

戻り値I/O操作が保留されている場合はtrue。 SocketAsyncEventArgs。eパラメータの完了イベントは、操作の完了時に発生します。 I/O操作が同期して完了した場合はfalseを返します。この場合、eパラメータのSocketAsyncEventArgs.Completedイベントは発生せず、パラメータとして渡されたeオブジェクトは、操作の結果を取得するためにメソッド呼び出しが返された直後に検査されます。

したがって、ReceiveAsyncコールの戻り値を確認する必要があります。そのtrueSocketAsyncEventArgs.Completedイベントを購読している場合。偽の場合はすぐにSocketAsyncEventArgsをチェックして結果を確認してください。

+0

ありがとうございますが、保留中の場合(クライアントからの入力を待っていると思われます)、キャンセルします。また、保留中でない場合は、保留にしたくありません。 – colmde

+0

申し訳ありませんが、私はコメントを編集することはできませんが、:私は 'ReceiveAsync()'が既に呼び出されていることを確認したい。 (既に保留中です)。もしそうなら、これをキャンセルしてください。チェックを行うために 'ReceiveAsync()'をもう一度呼び出すと、同じ例外が発生しますが、今回は 'SetBuffer()'ではなく)この呼び出しから取得します。 – colmde

0

具体的な質問にはあまりお答えできませんが、現時点での回避策はAcceptSocket.BytesAvailableの値を確認し、ReceiveAsync()を呼び出す前に値が0以上になるまで待ちます。そうすれば、最初にSendAsync()に電話する必要がある場合は、中断することができます。

これは少し効率的ではないと私は考えていますが、同時に最大50人のクライアントが接続する可能性があることを考慮すれば、どの程度スケーラビリティがあるのか​​は分かりませんが、今のところ。

関連する問題