//  下面是重点了
// 主窗体
 public partial class frmMain : Form
    {   
      // 仪表图形容器 图片用来显示仪表状态,TOOLTIP显示设备的实时数据
        private List<PictureBox> m_picList = new List<PictureBox>();
      // 取数据的线程, 定时做下面的工作:1 发送命令 2 检测网络链接状态
      private Thread m_thrdGetMeterStatus = null;
        DataTable m_errTable = new DataTable();// 错误数据表,仪表的错误数据都添加到这里,并显示
       // 由于动态从硬盘读取图片会更快的增加内存数量,我采用了静态的方法,把图片在程序启动时就放入
        public static Image[] m_highVImage = new Image[2];// 高压
        public static Image[] m_lowVImage = new Image[2];// 低压
        public static Image[] m_incomingImage = new Image[2];// 进线
        public static Image[] m_blueWaveImage = new Image[2];// 有源滤波
       // ...
        // 初始化SOCKET
        private void InitAsySocket()
        {
            // IP PORT
            m_sHostIP = CLoadMeters.ReadIni("HOST", "IP");
            m_iPort = int.Parse(CLoadMeters.ReadIni("HOST", "PORT").Trim());
            Socket client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            m_client = new AsySocket(client);
            m_client.OnStreamDataAccept += new StreamDataAcceptHandler(OnStreamAccept);
            m_client.OnClosed += new AsySocketClosedEventHandler(OnClosed);
            // 连接      
            if (pingHost(m_sHostIP))
            {
                m_client.Connet(m_sHostIP, m_iPort);
                Thread.Sleep(1500);
                if (!m_client.connected)
                {
                    //MessageBox.Show("连接失败,请检查网络配置。", "错误", MessageBoxButtons.OK);
                    lbConnectionStatus.Text = "通讯状态:断开";
                }
            }
        }
 // 数据接收
        private void OnStreamAccept(string AccepterID, byte[] AccepterData)
        {
            try
            {
                int max = g_iBufferCurrLength + AccepterData.Length;
                if (max > BUFFER_MAXLENGTH) max = BUFFER_MAXLENGTH;
                for (int i = g_iBufferCurrLength; i < max; i++)
                {
                    g_byTotalBuffer[i] = AccepterData[i-g_iBufferCurrLength];
                }
                g_iBufferCurrLength = max;
                processBuffer();         
            }
            catch (SocketException err)
            {
                throw err;
            }
        }
// 未完
}    

解决方案 »

  1.   


    //  下面是重点了
    // 主窗体
     public partial class frmMain : Form
        {   
          // 仪表图形容器 图片用来显示仪表状态,TOOLTIP显示设备的实时数据
            private List<PictureBox> m_picList = new List<PictureBox>();
          // 取数据的线程, 定时做下面的工作:1 发送命令 2 检测网络链接状态
          private Thread m_thrdGetMeterStatus = null;
            DataTable m_errTable = new DataTable();// 错误数据表,仪表的错误数据都添加到这里,并显示
           // 由于动态从硬盘读取图片会更快的增加内存数量,我采用了静态的方法,把图片在程序启动时就放入
            public static Image[] m_highVImage = new Image[2];// 高压
            public static Image[] m_lowVImage = new Image[2];// 低压
            public static Image[] m_incomingImage = new Image[2];// 进线
            public static Image[] m_blueWaveImage = new Image[2];// 有源滤波
           // ...
            // 初始化SOCKET
            private void InitAsySocket()
            {
                // IP PORT
                m_sHostIP = CLoadMeters.ReadIni("HOST", "IP");
                m_iPort = int.Parse(CLoadMeters.ReadIni("HOST", "PORT").Trim());
                Socket client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                m_client = new AsySocket(client);
                m_client.OnStreamDataAccept += new StreamDataAcceptHandler(OnStreamAccept);
                m_client.OnClosed += new AsySocketClosedEventHandler(OnClosed);
                // 连接      
                if (pingHost(m_sHostIP))
                {
                    m_client.Connet(m_sHostIP, m_iPort);
                    Thread.Sleep(1500);
                    if (!m_client.connected)
                    {
                        //MessageBox.Show("连接失败,请检查网络配置。", "错误", MessageBoxButtons.OK);
                        lbConnectionStatus.Text = "通讯状态:断开";
                    }
                }
            }
     // 数据接收
            private void OnStreamAccept(string AccepterID, byte[] AccepterData)
            {
                try
                {
                    int max = g_iBufferCurrLength + AccepterData.Length;
                    if (max > BUFFER_MAXLENGTH) max = BUFFER_MAXLENGTH;
                    for (int i = g_iBufferCurrLength; i < max; i++)
                    {
                        g_byTotalBuffer[i] = AccepterData[i-g_iBufferCurrLength];
                    }
                    g_iBufferCurrLength = max;
                    processBuffer();         
                }
                catch (SocketException err)
                {
                    throw err;
                }
            }
    // 未完
    }    
      

  2.   

        // 数据接收
            private void OnStreamAccept(string AccepterID, byte[] AccepterData)
            {
                try
                {
                    int max = g_iBufferCurrLength + AccepterData.Length;
                    if (max > BUFFER_MAXLENGTH) max = BUFFER_MAXLENGTH;
                    for (int i = g_iBufferCurrLength; i < max; i++)
                    {
                        g_byTotalBuffer[i] = AccepterData[i-g_iBufferCurrLength];
                    }
                    g_iBufferCurrLength = max;
                    processBuffer();         
                }
                catch (SocketException err)
                {
                    throw err;
                }
            }        //委托 状态
            private void delegateShowStatus(PictureBox picb, int meterID, int status,int index)
            {            MeterRealData rd = CLoadMeters.getMeterDetail(int.Parse(picb.Tag.ToString()));
                if (rd == null) return ;            
                if (rd.Status == 0 && status==1)
                {
                    if (rd.ItemType == enmItemType.EM_LOWVL || rd.ItemType == enmItemType.EM_LOWVR)// 低压
                    {
                        picb.Image = m_lowVImage[0];
                    }
                    else if (rd.ItemType == enmItemType.EM_BLUEVL || rd.ItemType == enmItemType.EM_BLUEVR)//  有源
                    {
                        picb.Image = m_blueWaveImage[0];
                    }
                    else if (rd.ItemType == enmItemType.EM_INCOMINGL || rd.ItemType == enmItemType.EM_INCOMINGR)// 进线
                    {
                        picb.Image = m_incomingImage[0];
                    }
                    else// 高压
                    {
                        picb.Image = m_highVImage[0];
                    } 
                    DataRow row = m_errTable.NewRow();
                    row[0] = CLoadMeters.ReadIni("ITEM" + (index+1).ToString(), "CABINET");
                    row[1] = rd.Name;
                    row[2] = "通讯恢复";
                    row[3] = DateTime.Now;
                    row[4] = rd.ID;
                    m_errTable.Rows.InsertAt(row, 0);
                }
                else if (rd.Status == 1 && status == 0)
                {
                 
                    if (rd.ItemType == enmItemType.EM_LOWVL || rd.ItemType == enmItemType.EM_LOWVR)// 低压
                    {
                        picb.Image = m_lowVImage[1];
                    }
                    else if (rd.ItemType == enmItemType.EM_BLUEVL || rd.ItemType == enmItemType.EM_BLUEVR)//  有源
                    {
                        picb.Image = m_blueWaveImage[1];
                    }
                    else if (rd.ItemType == enmItemType.EM_INCOMINGL || rd.ItemType == enmItemType.EM_INCOMINGR)// 进线
                    {
                        picb.Image = m_incomingImage[1];
                    }
                    else// 高压
                    {
                        picb.Image = m_highVImage[1];
                    }                DataRow row = m_errTable.NewRow();
                    row[0] = CLoadMeters.ReadIni("ITEM" +  (index+1).ToString(), "CABINET");
                    row[1] = rd.Name;
                    row[2] = "通讯失败";
                    row[3] = DateTime.Now;
                    row[4] = rd.ID;
                    m_errTable.Rows.InsertAt(row, 0);
                    
                }
                 
                // 最多保存10条
                if (m_errTable.Rows.Count > 10)
                {
                    m_errTable.Rows.Remove(m_errTable.Rows[10]);
                }            ttpMeter.ShowAlways = true;
            }
            //委托 数据
            private void delegateShowData(PictureBox picb, MeterRealData realdata )
            {
                string sTtpMeter= "" ;
                // 获取 REALDATA的数据 
                for (int i = 0; i < realdata.DataName.Length; i++)
                {
                    sTtpMeter += realdata.DataName[i] + ":" + realdata.DataValue[i] + "\n";
                }            
                ttpMeter.SetToolTip(picb, sTtpMeter);
                ttpMeter.ToolTipTitle = realdata.Name;
                ttpMeter.ShowAlways = true;
            }        // 缓存数据并处理
            private void processBuffer()
            {
               
                try
                {
                    while (true)
                    {
                        // 长度不够
                        if (g_iBufferCurrLength < 17) break ;
                        //  获取回数
                        byte[] byTmp;
                        int iDataType = -1;
                        int iStartPos = 0, iEndPos = 0;
                        for (int i = 0; i < g_iBufferCurrLength - 19; i++)//  找开始位
                        {
                            if (g_byTotalBuffer[i] == 0x68)
                            {
                                iStartPos = i;
                                break;
                            }
                        }
                        ///功能码
                        if (g_byTotalBuffer[iStartPos + 5] == 0x1)// 状态
                        {
                            iDataType = 0;
                        }
                        else if (g_byTotalBuffer[iStartPos + 5] == 0x4)// 实时
                        {
                            iDataType = 1;
                        }
                        else// 数据错误
                        {
                            shortCut(iStartPos + 1);
                            g_iBufferCurrLength -= iStartPos + 1;
                            continue;
                        }//end of( if (g_byTotalBuffer[iStartPos + 5] == 0x1))
                        iEndPos = iStartPos + g_byTotalBuffer[iStartPos + 7] + 9;
                        if (g_byTotalBuffer[iEndPos] != 0x16)
                        {
                            shortCut(iStartPos + 1);
                            g_iBufferCurrLength -= iStartPos + 1;
                            continue;
                        }
                        // 获取到了正确的信息
                        byTmp = new byte[iEndPos - iStartPos + 1];
                        for (int i = 0; i < byTmp.Length; i++)
                        {
                            byTmp[i] = g_byTotalBuffer[iStartPos + i];
                        }                    uint uistationid = 0, uimeterid = 0, uiDataID = 0;// 站号 设备号 数据号
                        string sValue = "";                                 // 数据
                        int iStatus = 0;                                    // 状态                    if (iDataType == 0)
                        {
                            CGetDeviceInfo.Unpack_GetStatus(byTmp, out uistationid, out uimeterid, out iStatus);
                            for (int j = 0; j < m_picList.Count; j++)
                            {
                                if (m_picList[j].Tag.ToString() == uimeterid.ToString())
                                {
                                    if (m_picList[j].InvokeRequired)
                                    {
                                        /**/
                                        /**由于windows窗体及其他控件不具备跨线程的能力,
                                     * 所以这里必须调用控件的异步委托方法
                                     */
                                        this.m_picList[j].Invoke(new showStaus(delegateShowStatus),
                                            new object[] { m_picList[j], (int)uimeterid, iStatus,j});
                                        break;
                                    }
                                }
                            }
                            updateMeterStatus(uimeterid, iStatus);
                        }
                        else if (iDataType == 1)
                        {                        CGetDeviceInfo.Unpack_GetMeterReall(byTmp, out uistationid, out uimeterid, out uiDataID, out sValue);
                            MeterRealData rd = updateMeterReal(uimeterid, uiDataID, sValue);
                            if (rd != null)
                            {
                                for (int j = 0; j < m_picList.Count; j++)
                                {
                                    if (m_picList[j].Tag.ToString() == uimeterid.ToString())
                                    {
                                        if (m_picList[j].InvokeRequired)
                                        {
                                            /**/
                                            /**由于windows窗体及其他控件不具备跨线程的能力,
                                         * 所以这里必须调用控件的异步委托方法
                                         */
                                            this.m_picList[j].Invoke(new showData(delegateShowData),
                                                new object[] { m_picList[j], rd });
                                            break;
                                        }
                                    }
                                }
                            }
                                                }
                        // 更新BUFF
                        shortCut(iEndPos + 1);
                        g_iBufferCurrLength -= iEndPos + 1;
                        if (g_iBufferCurrLength < 0) g_iBufferCurrLength = 0;
                        Thread.Sleep(200);
                        byTmp = null;
                    }
                }
                catch (Exception err)
                {            }
            }
    基本上就这些了,高手帮忙看下,分不够可以加
      

  3.   

    使用流完毕后要关闭。
    不再使用的Image要Image.Dispose()
      

  4.   

    是的,把很多的东西都装入内存,当然很吃内存啦  要记得释放资源~~[align=center]***********************************************************
                       欢迎使用 CSDN 小秘书
                  CSDN 小秘书下载
    ***********************************************************[/align]
      

  5.   

    能说的详细点么,不是很清楚。
    我的IMAGE全程在使用,我尝试了picb.image.dispose();但是这样操作就会导致运行错误。
      

  6.   

    静态的变量,没事的,关键是你内存增长的情况如何?
    如果只是少量增加,不是大碍,GC机制的.net会在某个时刻运行垃圾回收的。
      

  7.   

    找个内存测试工具.net memory profiler找个工具可以帮助你找到究竟是哪个东西一直在占内存,没有释放。一般都是因为非托管的资源用过没有释放,然后又不停的申请,这样就造成了内存泄露
      

  8.   

    你这个是多线程么?看到了invoke...,如果是多线程,你的有些变量好像没有锁,是不是会出问题?
    造成大量Exception对象被创建。
      

  9.   

    谢谢你的提醒,我之前一直做C++,没有做过.NET,真需要好好研究研究.