3

データを送信するときに最初に競合状態が発生しました。問題は、複数の SocketAsyncEventArgs を使用してデータを送信できるようにしていたことでしたが、最初のパケットは 2 番目のパケットの前に完全には送信されませんでした。すべてのデータが送信されるまでループするバッファに収まらず、最初のパケットが小さい 2 番目のパケットよりも大きかったため、2 番目のパケットが送信され、最初のパケットの前にクライアントに到達しました。

データの送信に使用するオープン接続に 1 つの SocketAyncEventArgs を割り当て、セマフォを使用してアクセスを制限し、完了したら SocketAsyncEventArgs コールバックを行うことでこれを解決しました。

すべてのデータが送信され、次の送信の準備が整ったときにコールバックされるため、これは正常に機能します。これに関する問題は、開いている接続にデータをランダムに送信したいときにブロックが発生し、大量のデータが送信されてスレッドがブロックされることです。

私はこれに対する回避策を探しています。データの送信が要求されたときにキューを作成することを考えました。パケットをキューに追加し、1 SocketAsyncEventArgs を単純にループしてそのデータを送信します。

しかし、スケーラブルでありながらこれを効率的に行うにはどうすればよいでしょうか? リクエストされた順序でパケットを送信している間は、できるだけブロックを避けたい.

どんな助けにも感謝します!

4

1 に答える 1

4

If the data needs to be kept in order, and you don't want to block, then you need to add a queue. The way I do this is by tracking, on my state object, whether we already have an active send async-loop in process for that connection. After enqueue (which obviously must be synchronized), just check what is in-progress:

    public void PromptToSend(NetContext context)
    {
        if(Interlocked.CompareExchange(ref writerCount, 1, 0) == 0)
        { // then **we** are the writer
            context.Handler.StartSending(this);
        }
    }

Here writerCount is the count of write-loops (which should be exactly 1 or 0) on the connection; if there aren't any, we start one.

My StartSending tries to read from that connection's queue; if it can do so, it does the usual SendAsync etc:

if (!connection.Socket.SendAsync(args)) SendCompleted(args);

(note that SendCompleted here is for the "sync" case; it would have got to SendCompleted via the event-model for the "async" case). SendCompleted repeats this "dequeue, try send async" step, obviously.

The only thing left is to make sure that when we try to dequeue, we note the lack of action if we find nothing more to do:

        if (bufferedLength == 0)
        {  // nothing to do; report this worker as inactive
            Interlocked.Exchange(ref writerCount, 0);
            return 0;
        }

Make sense?

于 2012-07-25T11:35:52.160 に答える