Тайм-аут асинхронного сокета .net проверка безопасности потока

http://msdn.microsoft.com/en-us/library/system.net.sockets.socketasynceventargs.aspx

Начиная с приведенного выше примера msdn, я пытаюсь написать проверку тайм-аута, которая закроет неактивные клиентские сокеты и освободит ресурсы.

Это то, что я придумал. Но я не уверен, является ли он полностью поточно-ориентированным и есть ли лучший способ сделать это. Я надеюсь, что кто-то может дать некоторые советы.

void IO_Completed(object sender, SocketAsyncEventArgs e)
{
    if (e.SocketError != SocketError.Success)
    {
        CloseClientSocket(e);
        return;
    }

    if (1 < Interlocked.CompareExchange(ref token.Status, 1, 0))
        return;

    switch (e.LastOperation)
    {
        case SocketAsyncOperation.Receive:
            ProcessReceive(e);
            break;
        ...
    }

    token.LastActive = Environment.TickCount;
    Interlocked.CompareExchange(ref token.Status, 0, 1);
}

void ProcessReceive(SocketAsyncEventArgs e)
{
    AsyncUserToken token = (AsyncUserToken)e.UserToken;
    if (e.BytesTransferred > 0)
        if (!token.Socket.SendAsync(e))
            ProcessSend(e);
    else
        CloseClientSocket(e);
}

void ProcessSend(SocketAsyncEventArgs e)
{
    AsyncUserToken token = (AsyncUserToken)e.UserToken;
    if (!token.Socket.ReceiveAsync(e))
        ProcessReceive(e);
}

TimeoutCheck будет выполняться один раз каждые 20 секунд. allReadWriteArgs - это массив со всеми SocketAsyncEventArgs. После закрытия сокета IO_Completed будет вызываться с SocketError.OperationAborted.

void TimeoutCheck(object state)
{
    AsyncUserToken token;
    int timeout = Environment.TickCount - 20000;
    for (int i = 0; i < allReadWriteArgs.Length; i++)
    {
        token = (AsyncUserToken)allReadWriteArgs[i].UserToken;
        if (token.LastActive < timeout)
            if (0 == Interlocked.CompareExchange(ref token.Status, 2, 0))
                Interlocked.Exchange(ref token.Socket, null).Close();
    }
}


void CloseClientSocket(SocketAsyncEventArgs e)
{
    AsyncUserToken token = e.UserToken as AsyncUserToken;

    if (token.Socket != null)
    {
        try
        {
            token.Socket.Shutdown(SocketShutdown.Both);
        }
        catch (SocketException) { }
        token.Socket.Close();
    }

    token.Status = 2;
    bufferManager.FreeBuffer(e);
    readWritePool.Push(e);
    ...
}

Ответы на вопрос(1)

Ваш ответ на вопрос