開始/終了デザインパターンで非同期ソケットを使用しているアプリケーションがあります。
新しい接続を受信するたびに、オブジェクトを作成してコレクションに保存します。このオブジェクトは、それ自体の中にソケット接続も格納し、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();
}
}