如何正确处理多线程/异步应用程序中的对象?

时间:2013-02-04 19:46:42

标签: c# multithreading sockets

我有一个使用带有开始/结束设计模式的异步套接字的应用程序。

每当我收到一个新连接时,我都会创建一个对象并将其存储在一个集合中。此对象还将套接字连接存储在其自身中,并将在begin方法“object state”中传递。

现在服务器异步运行,发送,接收等,在任何给定时间都有一个对象执行多个代码路径。

我不明白的是: 如果我调用一个传入当前对象和另一个线程的函数,那个对象就被处理了,那么当前执行代码的另一个对象会发生什么。

编辑:

ex。)如果你看一下调用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();
    }
}

1 个答案:

答案 0 :(得分:0)

如果一个对象放置在一个线程上,它将被置于所有线程上。如果在其他线程处理它之后对它执行任何操作,它应该(但不保证)抛出ObjectDisposedException。

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

如果你在一个线程上处理一个对象,而另一个线程可能希望使用它,那么你做错了什么。考虑以确定的方式控制单个线程上对象的生命周期。