0

開始/終了デザインパターンで非同期ソケットを使用しているアプリケーションがあります。

新しい接続を受信するたびに、オブジェクトを作成してコレクションに保存します。このオブジェクトは、それ自体の中にソケット接続も格納し、beginメソッドの「オブジェクト状態」で渡されます。

サーバーが非同期で実行され、送信、受信などが行われるようになったため、オブジェクトに対して常に複数のコードパスが実行されます。

私が理解していないのは、現在のオブジェクトと別のスレッドを渡す関数を呼び出すと、そのオブジェクトは破棄されたばかりで、現在実行中のコード内にある他のオブジェクトはどうなるかということです。

編集:

例)doSomthing()を呼び出しているReadDataCallback()を見ると。「device」オブジェクトを使用してdoSomthing()を呼び出そうとしているが、対応するデバイスでSendCallback()に例外があった場合。doSomthing()を呼び出そうとしているデバイスオブジェクトはどのような状態ですか?

これがコード例です。

void waitForData(MyDevice device)
{
    try
    {
        if (device.SocketState.IsSSL)
        {
            device.SocketState.sslStream.BeginRead(device.SocketState.DataBuffer, 0, device.SocketState.DataBuffer.Length, m_readDataCallback, device);
        }
        else
        {
            device.SocketState.DeviceSocket.BeginReceive(device.SocketState.DataBuffer, 0, device.SocketState.DataBuffer.Length, SocketFlags.None, m_readDataCallback, device);
        }
    }
    catch (SocketException se)
    {
        DisconnectAndRemove(device);
    }
}

public void ReadDataCallback(IAsyncResult ar)
{
    MyDevice device = (MyDevice)ar.AsyncState;
    try
    {
        Queue<kustompacket> qps = null;
        int iRx = 0;

        if (device.SocketState.IsSSL)
        {
            iRx = device.SocketState.sslStream.EndRead(ar);
            if (iRx == 0)
            {
                DisconnectAndRemove(device);
            }
            else if (iRx > 0)
            {
                device.CircularBuff.Add(iRx, device.SocketState.DataBuffer);
                qps = device.CircularBuff.ReadPackets();
                doSomthing(device);
            }
        }
        else
        {
            if (device.SocketState.DeviceSocket != null)
            {
                if (device.SocketState.DeviceSocket.Connected)
                {
                    // Read data from the client socket.
                    iRx = device.SocketState.DeviceSocket.EndReceive(ar);
                    if (iRx == 0)
                    {
                        DisconnectAndRemove(device);
                    }
                    else if (iRx > 0)
                    {
                        device.CircularBuff.Add(iRx, device.SocketState.DataBuffer);
                        qps = device.CircularBuff.ReadEncryptedPackets(device.SocketState.SessionID);
                        doSomthing(device);
                    }
                }
            }
        }

        if (qps != null)
        {
            MyDelegate meh = new MyDelegate(HandleDataReceived);
            meh.BeginInvoke(device, qps, null, null);
        }

        if (iRx != 0)
        {
            waitForData(device);
        }
    }
    catch (ObjectDisposedException ode)
    {
        //Socket has been closed
        //DisconnectAndRemove(device);
    }
    catch (SocketException se)
    {
        //if (se.ErrorCode == 10054) // Error code for Connection reset by peer
        //{
        DisconnectAndRemove(device);
        //}
    }
    catch (Exception ex)
    {
        DisconnectAndRemove(device);
    }
}


public void SendCallback(IAsyncResult ar)
{
    MyDevice device = (MyDevice)ar.AsyncState;
    try
    {
        // Complete sending the data to the remote device.
        if (device.SocketState.IsSSL)
        {
            device.SocketState.sslStream.EndWrite(ar);
        }
        else
        {
            int bytesSent = device.SocketState.DeviceSocket.EndSend(ar);
        }
        device.ResetAge();
    }
    catch (SocketException se)
    {
        DisconnectAndRemove(device);
    }
    catch (Exception ex)
    {
    }

    if (device.SocketState.IsSSL)
    {
        device.Write();
    }
}
4

1 に答える 1

0

オブジェクトが1つのスレッドに配置されている場合、そのオブジェクトはすべてのスレッドに配置されます。他のスレッドがそれを破棄した後に何かを行う場合、ObjectDisposedExceptionをスローする必要があります(ただし、保証されているわけではありません)。

http://msdn.microsoft.com/en-us/library/system.objectdisposedexception.aspx

別のスレッドがオブジェクトを処理することを期待しているときにオブジェクトをスレッドに配置している場合は、何か間違ったことをしています。決定論的な方法で単一スレッド上のオブジェクトの存続期間を制御することを検討してください。

于 2013-02-04T19:54:50.080 に答える