using System;
using System.Collections.Generic;
using System.Text;
using Opc;
using Opc.Da;
using OpcCom;
using System.Threading;
using System.Data;
using DBFactory;
using CommonLib;
namespace OPCClient
{
    public static class CCommonOPCClient
    {
        public static object lockob = new object();
        public static event CUpdateDBEventHandler UpdateDB;
        public static void OnUpdateDB(object sender,CUpdateDBChangeEventArgs e)
        {
            if (UpdateDB != null)
            {
                UpdateDB(sender, e);
            }
        }
        public static DBOperator dbo = new DBOperator();
        //20110726
        private static Dictionary<string, int> _connectCount = new Dictionary<string, int>(); //private static int _connectCount = 0;
        //20110726
        public static Dictionary<string, int> ConnectCount
        {
            get { return CCommonOPCClient._connectCount; }
            set { CCommonOPCClient._connectCount = value; }
        }
        //public static int ConnectCount
        //{
        //    get { return CCommonOPCClient._connectCount; }
        //    set {
        //        if (value == 0)
        //        {
        //            _opcError = "";
        //        }
        //        CCommonOPCClient._connectCount = value; 
        //    }
        //}

        private static int[] _plcStates=null ;

        public static int[] PlcStates
        {
            get { return CCommonOPCClient._plcStates; }
            //set { CCommonOPCClient._plcStates = value; }
        }
        
        /// <summary>
        /// 20110309���ĵ����ڱ�ǩ���ݱ仯�¼�
        /// </summary>
        /// <param name="subscriptionHandle">�ͻ��˾��</param>
        /// <param name="requestHandle">������</param>
        /// <param name="values">��ǩֵ����</param>
        public static void OnDataChange(object subscriptionHandle, object requestHandle, ItemValueResult[] values)
        {
            lock (lockob)
            {
                //����subscriptionHandle��Ӧ�豸�����������豸���ࣨ��ͬ�����豸ͨѶ����֡��ͬ��
                //�ֱ�������ɣ���������翪�أ�PLC���������
                int deviceindex = 0;
                try
                {
                    if (subscriptionHandle.ToString().IndexOf("split") >= 0)
                    {
                        deviceindex = System.Convert.ToInt32(subscriptionHandle.ToString().Substring(5));
                        if (values[0].Quality != Quality.Good) return;
                        Array arr = (Array)values[0].Value;
                        byte[] GDKG = null;

                        GDKG = new byte[arr.GetLength(0)];
                        Array.Copy(arr, GDKG, arr.GetLength(0));
                        //object lockthis = new object();
                        //lock (UpdateDB)
                        {
                            CUpdateDBChangeEventArgs udbe = new CUpdateDBChangeEventArgs(deviceindex, GDKG, null);
                            OnUpdateDB("OPCClient.CCommonOPCClient.OnDataChange", udbe);
                        }

                    }
                    else
                    {

                        deviceindex = System.Convert.ToInt32(subscriptionHandle);
                        Array arr = (Array)values[0].Value;
                        byte[] itemnamevalue = new byte[arr.GetLength(0)];
                        Array.Copy(arr, itemnamevalue, arr.GetLength(0));
                        int head = 0;
                        head = itemnamevalue[0];//��д��־
                        //if (head != 1) return;
                        //object lockthis = new object();
                        //lock (UpdateDB)
                        {
                            CUpdateDBChangeEventArgs udbe = new CUpdateDBChangeEventArgs(deviceindex, null, itemnamevalue);
                            OnUpdateDB("OPCClient.CCommonOPCClient.OnDataChange", udbe);
                        }
                    }
                    //����PLC�������ֽڵ������飨����S7Connection�����߶˲���Ҫ



                }
                catch (Exception ex)
                {//20120420
                    _opcError = string.Format("OPC�����������¼��쳣��{0},{1}", ex.Message, ex.StackTrace);
                    CUpdateDBChangeEventArgs udbe = new CUpdateDBChangeEventArgs(deviceindex, null, null);
                    OnUpdateDB("OPCClient.CCommonOPCClient.OnDataChange", udbe);


                }
            }
        }

        

        //WriteComplete�ص�
        public static void OnWriteComplete(object requestHandle, Opc.IdentifiedResult[] values)
        {
            /*Console.WriteLine("�����첽дname:{0},value:{1}", values[0].ItemName, values[0].GetType());
            if ((int)requestHandle == 2)
                Console.WriteLine("�¼��źž��Ϊ{0}", requestHandle);*/
        }

        static private string _PLCconnectionID = "S7:[S7 connection_1]";
        /// <summary>
        /// ����PLC���ӵ�ID�����磺"S7:[S7 connection_1]"
        /// ����"S7:[@LOCALSERVER]"
        /// </summary>
        public static string PlcConnectionID
        {
            get { return CCommonOPCClient._PLCconnectionID; }
            set { CCommonOPCClient._PLCconnectionID = value; }
        }
        static private string _opcError;
        static private bool _IfConnectOPCServer=false ;
        static private string _hostname;
        /// <summary>
        /// OPC Server�Ļ������ƻ���IP��ַ
        /// </summary>
        public static string Hostname
        {
            get { return CCommonOPCClient._hostname; }
            set { CCommonOPCClient._hostname = value; }
        }
        static private string _progID;
        /// <summary>
        /// OPC Server�ij����ʶ�����磺OPC.SimaticNET
        /// </summary>
        public static string ProgID
        {
            get { return CCommonOPCClient._progID; }
            set { CCommonOPCClient._progID = value; }
        }
        public static string OpcError
        {
            get { return CCommonOPCClient._opcError; }
            set { CCommonOPCClient._opcError = value; }
        }
        static private Opc.Da.Server m_server = null;//�������ݴ�ȡ������
        static private Opc.Server[] servers;
        static private Opc.Da.Subscription subscription = null;//��������󣨶����ߣ�
        static private Opc.Da.SubscriptionState state = null;//�����飨�����ߣ�״̬���൱��OPC�淶����IJ���
        static private Opc.Da.Subscription _readSubscription = null;//��������󣨶����ߣ�
        //static private Opc.Da.SubscriptionState _readstate = null;//�����飨�����ߣ�״̬���൱��OPC�淶����IJ���
        static private Opc.Da.Subscription _writeSubscription = null;//��������󣨶����ߣ�
        static private Opc.Da.SubscriptionState _writestate = null;//�����飨�����ߣ�״̬���൱��OPC�淶����IJ���
        static private Opc.Da.Subscription _tempSubscription = null;//��������󣨶����ߣ�
        static private Opc.Da.SubscriptionState _tempstate = null;//�����飨�����ߣ�״̬���൱��OPC�淶����IJ���
        static private Opc.IDiscovery m_discovery = new OpcCom.ServerEnumerator();//����ö�ٻ���COM�������Ľӿڣ������������еĴ����������
        /// <summary>
        /// ���豸��������Ӧ�豸���ġ�
        /// </summary>
        public static SubscriptionCollection  SubscriptionGroup = new SubscriptionCollection();//��������󼯺ϣ������߼��ϣ�//20110309
        //public static System.Collections.Hashtable SubscriptionG = new System.Collections.Hashtable();
        //static Model.MDevice devinfo;//20110309
        /// <summary>
        /// 20110309ÿ���豸����һ�����ĺ�DataChange�¼�
        /// </summary>
        public static void CreateSubscriptionGroup()
        {
            if (_IfConnectOPCServer == false)
            {
                _hostname = CommonClassLib.AppSettings.GetValue("HostName");
                _progID = CommonClassLib.AppSettings.GetValue("OPCProgID");
                if (ConnectOPCServer(_hostname, _progID) == false) return ;
            }
            //SELECT F_DeviceIndex, F_DBW2Address, F_DBWGetLength, F_S7Connection,F_SplitByte FROM T_Base_Device where f_devicekindindex<>28 and  F_DBW2Address >=0 and F_DBWGetLength>0 order by F_DeviceIndex asc
            DataView dv = dbo.ExceSQL("SELECT F_ReadSubscription, F_DeviceIndex, F_DBW2Address, F_DBWGetLength, F_S7Connection, F_SplitByte FROM T_Base_Device WHERE (F_ReadSubscription IS NOT NULL) AND (F_ReadSubscription =F_DeviceIndex) ORDER BY F_ReadSubscription").Tables[0].DefaultView;
            if (dv.Count > 0)
            {
                if (dv.Count < SubscriptionGroup.Count) return;
            }
            DataView dvx; 
            for (int i = 0; i < dv.Count; i++)
            {
                //string dt = DateTime.Now.Minute.ToString() + "-" + DateTime.Now.Second.ToString() + "-" + DateTime.Now.Millisecond.ToString();
                dvx = dbo.ExceSQL(string.Format("SELECT (MAX(F_DBW2Address) + F_DBWGetLength) as maxdbw2 FROM T_Base_Device WHERE (F_ReadSubscription = {0})  AND (F_DeviceKindIndex <> 33) GROUP BY F_DBWGetLength ORDER BY maxdbw2 DESC", dv[i]["F_ReadSubscription"])).Tables[0].DefaultView;
                if (dvx.Count > 0)
                {

                    //�趨�豸����״̬
                    _tempstate = new Opc.Da.SubscriptionState();//�飨�����ߣ�״̬���൱��OPC�淶����IJ���
                    _tempstate.Name = dv[i]["F_ReadSubscription"].ToString();//����
                    
                    _tempstate.ServerHandle = null;//���������������ľ����
                    _tempstate.ClientHandle = dv[i]["F_ReadSubscription"].ToString();//�ͻ��˸��������ľ����
                    _tempstate.Active = true;//������顣
                    _tempstate.UpdateRate = 500;//ˢ��Ƶ��Ϊ500���롣
                    _tempstate.Deadband = 0;// ����ֵ����Ϊ0ʱ���������˸������κ����ݱ仯��֪ͨ�顣
                    _tempstate.Locale = null;//�����õ���ֵ��
                    //�����豸����
                    _tempSubscription = (Opc.Da.Subscription)m_server.CreateSubscription(_tempstate);//�����豸����
                    //�����¼�

                    
                    //���ӱ�ǩ
                    ////�����item�б�
                    Item[] items = new Item[1];//�����������item//20111110

                    int ii = 0;//20111110������
                    items[ii] = new Item();//����һ����Item����
                    items[ii].ClientHandle = Guid.NewGuid().ToString();//�ͻ��˸������������ľ����
                    items[ii].ItemPath = null; //���������ڷ������е�·����
                    items[ii].ItemName = dv[i]["F_S7Connection"].ToString() +
                        Model.CGeneralFunction.DBGet + ",byte" +
                        dv[i]["F_DBW2Address"].ToString() + "," +
                        (System.Convert.ToInt32(System.Convert.ToInt32(dvx[0]["maxdbw2"]) - System.Convert.ToInt32(dv[i]["F_DBW2Address"]))).ToString(); //���������ڷ������е����֡�
                    
                    //���Ӷ�Item
                    ItemResult[] irs = _tempSubscription.AddItems(items);
                    _tempSubscription.DataChanged += new Opc.Da.DataChangedEventHandler(OnDataChange);
                    if (SubscriptionGroup.Contains(_tempSubscription) == false)
                    {
                        SubscriptionGroup.Add(_tempSubscription);
                    }
                    
                }
            }
            dv = dbo.ExceSQL("SELECT F_ReadSubscription, F_DeviceIndex, F_DBW2Address, F_DBWGetLength, F_S7Connection, F_SplitByte FROM T_Base_Device WHERE (F_ReadSubscription IS NOT NULL) AND (F_DeviceKindIndex=33)  ORDER BY F_ReadSubscription").Tables[0].DefaultView;
            
            for (int i = 0; i < dv.Count; i++)
            {
                //�趨�豸����״̬
                _tempstate = new Opc.Da.SubscriptionState();//�飨�����ߣ�״̬���൱��OPC�淶����IJ���
                _tempstate.Name = "split" + dv[i]["F_ReadSubscription"].ToString();//����
                _tempstate.ServerHandle = null;//���������������ľ����
                _tempstate.ClientHandle ="split"+ dv[i]["F_ReadSubscription"].ToString();//�ͻ��˸��������ľ����
                _tempstate.Active = true;//������顣
                _tempstate.UpdateRate = 500;//ˢ��Ƶ��Ϊ500���롣
                _tempstate.Deadband = 0;// ����ֵ����Ϊ0ʱ���������˸������κ����ݱ仯��֪ͨ�顣
                _tempstate.Locale = null;//�����õ���ֵ��
                //�����豸����
                _tempSubscription = (Opc.Da.Subscription)m_server.CreateSubscription(_tempstate);//�����豸����
                //���ӱ�ǩ
                ////�����item�б�
                Item[] items = new Item[1];//�����������item//20111110

                int ii = 0;//20111110������
                items[ii] = new Item();//����һ����Item����
                items[ii].ClientHandle = Guid.NewGuid().ToString();//�ͻ��˸������������ľ����
                items[ii].ItemPath = null; //���������ڷ������е�·����
                items[ii].ItemName = dv[i]["F_S7Connection"].ToString() +
                    Model.CGeneralFunction.DBGet + ",byte" +
                    dv[i]["F_DBW2Address"].ToString() + "," +
                    (System.Convert.ToInt32(dv[i]["F_DBWGetLength"])).ToString(); //���������ڷ������е����֡�

                //���Ӷ�Item
                ItemResult[] irs = _tempSubscription.AddItems(items);
                //�����¼�
                _tempSubscription.DataChanged += new Opc.Da.DataChangedEventHandler(OnDataChange);
                if (SubscriptionGroup.Contains(_tempSubscription) == false)
                {
                    SubscriptionGroup.Add(_tempSubscription);
                }
            }
        }
        /// <summary>
        /// ��ȡ����������OPC�������ı�ʶ��������
        /// </summary>
        /// <param name="hostname">��������</param>
        /// <returns></returns>
        public static List<string> GetOpcServers(string hostname)
        {
            try
            {
                ConnectData cd = new ConnectData(new System.Net.NetworkCredential(CommonClassLib.AppSettings.GetValue("OPCUsername"),
                    CommonClassLib.AppSettings.GetValue("OPCPassword")));//20120510
                
                servers = m_discovery.GetAvailableServers(Specification.COM_DA_20, hostname, cd);//20120510
                //daver��ʾ���ݴ�ȡ�淶�汾��Specification.COMDA_20����2.0�汾��
                //hostΪ���������null��ʾ����Ҫ�κ����簲ȫ��֤��
                if (servers != null)
                {
                    List<string> ser =new List<string>();;
                    foreach (Opc.Da.Server server in servers)
                    {
                        ser.Add(server.Name);
                    }
                    return ser;
                }
                return null;
            }
            catch (Exception ex)
            {
                _opcError = "��ȡOPC������ʱ��" + ex.Message;
                return null;
            }
        }
        /// <summary>
        /// ����ָ��������OPC������
        /// </summary>
        /// <param name="hostname">��������</param>
        /// <param name="ProgID">OPC�����������ʶ���磺"OPC.SimaticNET"</param>
        /// <returns></returns>
        public static bool ConnectOPCServer(string hostname, string ProgID)
        {
            try
            {
                
                GetOpcServers(hostname);
                if (ProgID.Contains(hostname) == false && hostname!="127.0.0.1")//20120510
                {
                    ProgID = hostname + "." + ProgID;
                }
                foreach (Opc.Da.Server server in servers)
                {
                    //server��Ϊ��Ҫ���ӵ�OPC���ݴ�ȡ��������
                    if (String.Compare(server.Name,  ProgID, true) == 0)//Ϊtrue���Դ�Сд
                    {
                        m_server = server;//�������ӡ�
                        break;
                        
                    }
                }
                //���ӷ�����
                if (m_server != null)//�ǿ����ӷ�����
                {
                    m_server.Connect();
                    _IfConnectOPCServer = true;
                    CreateItemGroup();
                    return true;
                }
                else
                {
                    _IfConnectOPCServer = false;
                    return false;
                }
                
            }
            catch (Exception ex)
            {
                _opcError ="����OPC���ݴ�ȡ������ʱ��"+ ex.Message;
                _IfConnectOPCServer = false;
                return false;
            }
            
        }
        /// <summary>
        /// ����OPC�飨�����ߣ����������ڱ�������
        /// </summary>
        /// <param name="groupname">OPC�飨�����ߣ�����</param>
        /// <param name="itemnames">ָ���������б�������,�����ֵ����"S7:[S7 connection_1]DB1,INT1"</param>
        /// <returns></returns>
        public static Opc.Da.Subscription CreateItemGroup(string groupname, string[] itemnames)
        {
            string[] itemName ;
            //����item�б�
            Item[] items;
            ItemResult[] irs;
            try
            {
                if (_IfConnectOPCServer == false)
                {
                    if (ConnectOPCServer(_hostname, _progID) == false) return null;
                }
                //�趨��״̬
                state = new Opc.Da.SubscriptionState();//�飨�����ߣ�״̬���൱��OPC�淶����IJ���
                state.Name = groupname;//����
                state.ServerHandle = null;//���������������ľ����
                state.ClientHandle = Guid.NewGuid().ToString();//�ͻ��˸��������ľ����
                state.Active = true;//������顣
                state.UpdateRate = 50;//ˢ��Ƶ��Ϊ100���롣
                state.Deadband = 0;// ����ֵ����Ϊ0ʱ���������˸������κ����ݱ仯��֪ͨ�顣
                state.Locale = null;//�����õ���ֵ��


                //������
                subscription = (Opc.Da.Subscription)m_server.CreateSubscription(state);//������

                //����Item�б�
                //��Ӧ����Ϊ:{Byte,Byte,Char,Short,String,Word,Boolean}
                itemName = itemnames;//{ "S7:[S7 connection_1]DB1,INT1", "S7:[@LOCALSERVER]DB1,INT20", "S7:[@LOCALSERVER]DB1,INT30", "S7:[@LOCALSERVER]DB1,INT50" };

                //����item�б�
                items = new Item[itemName.Length];//�����������item
                int i;
                for (i = 0; i < items.Length; i++)//item��ʼ����ֵ
                {
                    items[i] = new Item();//����һ����Item����
                    items[i].ClientHandle = Guid.NewGuid().ToString();//�ͻ��˸������������ľ����
                    items[i].ItemPath = null; //���������ڷ������е�·����
                    items[i].ItemName = itemName[i]; //���������ڷ������е����֡�
                }

                //����Item
                irs = subscription.AddItems(items);
                return subscription;
            }
            catch (Exception ex)
            {
                //if ((m_server == null) || (m_server.IsConnected == false))
                //{
                _IfConnectOPCServer = false;
                //}
                _opcError = "����OPC��ʱ��" + ex.Message;
                return null;
            }
            finally
            {
                itemName=null;
                //����item�б�
                items=null;
                irs=null;
            }
        }
        /// <summary>
        /// ����OPC�飨�����ߣ������������ڱ�������
        /// </summary>
        /// <param name="groupname">OPC�飨�����ߣ�����</param>
        /// <returns></returns>
        public static Opc.Da.Subscription CreateItemGroup(string groupname)
        {
            try
            {
                if (_IfConnectOPCServer == false)
                {
                    if (ConnectOPCServer(_hostname, _progID) == false) return null;
                }
                //�趨��״̬
                state = new Opc.Da.SubscriptionState();//�飨�����ߣ�״̬���൱��OPC�淶����IJ���
                state.Name = groupname;//����
                state.ServerHandle = null;//���������������ľ����
                state.ClientHandle = Guid.NewGuid().ToString();//�ͻ��˸��������ľ����
                state.Active = true;//������顣
                state.UpdateRate = 50;//ˢ��Ƶ��Ϊ100���롣
                state.Deadband = 0;// ����ֵ����Ϊ0ʱ���������˸������κ����ݱ仯��֪ͨ�顣
                state.Locale = null;//�����õ���ֵ��


                //������
                subscription = (Opc.Da.Subscription)m_server.CreateSubscription(state);//������

                
                return subscription;
            }
            catch (Exception ex)
            {
                //if ((m_server == null) || (m_server.IsConnected == false))
                //{
                _IfConnectOPCServer = false;
                //}
                _opcError = "����OPC��ʱ��" + ex.Message;
                return null;
            }
        }
        /// <summary>
        /// ��������Ĭ���飺read��write����ʱ��д��tempGroup
        /// </summary>
        /// <returns></returns>
        public static void  CreateItemGroup()
        {
            try
            {
                //if (_IfConnectOPCServer == false)
                //{
                //    if (ConnectOPCServer(_hostname, _progID) == false) return ;
                //}
                #region ������ȫ����ǩ��
                //20110216
                
                ////�趨��ȡ��״̬
                //_readstate = new Opc.Da.SubscriptionState();//�飨�����ߣ�״̬���൱��OPC�淶����IJ���
                //_readstate.Name = "readopc";//����
                //_readstate.ServerHandle = null;//���������������ľ����
                //_readstate.ClientHandle = Guid.NewGuid().ToString();//�ͻ��˸��������ľ����
                //_readstate.Active = true;//������顣
                //_readstate.UpdateRate = 50;//ˢ��Ƶ��Ϊ100���롣
                //_readstate.Deadband = 0;// ����ֵ����Ϊ0ʱ���������˸������κ����ݱ仯��֪ͨ�顣
                //_readstate.Locale = null;//�����õ���ֵ��
                ////���Ӷ���
                //_readSubscription = (Opc.Da.Subscription)m_server.CreateSubscription(_readstate);//������ȡ��
                //20110216
                //string[] itemName;
                //DataView dv = dbo.ExceSQL("SELECT F_S7Connection,F_DBW2Address,F_DBWGetLength  FROM T_Base_Device WHERE (F_DeviceKindIndex = 28)").Tables[0].DefaultView;
                //if (dv.Count > 0)
                //{
                //    itemName=new string[dv.Count];
                //    for(int i=0;i<dv.Count;i++)
                //    {
                //        itemName[i] = dv[i]["F_S7Connection"] + Model.CGeneralFunction.DBGet + ",byte"
                //            + dv[i]["F_DBW2Address"].ToString() + "," + ((int)dv[i]["F_DBWGetLength"]).ToString();
                //    }
                //    //{ "S7:[S7 connection_1]DB1,INT1", "S7:[@LOCALSERVER]DB1,INT20", "S7:[@LOCALSERVER]DB1,INT30", "S7:[@LOCALSERVER]DB1,INT50" };
                //}
                //else
                //{
                //    return ;
                //}
                ////�����item�б�
                //Item[] items = new Item[itemName.Length];//�����������item
                //int i;
                //for (i = 0; i < items.Length; i++)//item��ʼ����ֵ
                //{
                //    items[i] = new Item();//����һ����Item����
                //    items[i].ClientHandle = Guid.NewGuid().ToString();//�ͻ��˸������������ľ����
                //    items[i].ItemPath = null; //���������ڷ������е�·����
                //    items[i].ItemName =  itemName[i]; //���������ڷ������е����֡�
                //}

                ////���Ӷ�Item
                //ItemResult[] irs = _readSubscription.AddItems(items);
                //_plcStates = new int[System.Convert.ToInt32( devinfo28.Dbw2Getlength)];
                //_readSubscription.DataChanged += new Opc.Da.DataChangedEventHandler(OnDataChange);
                #endregion

                //�趨д��״̬
                _writestate = new Opc.Da.SubscriptionState();//�飨�����ߣ�״̬���൱��OPC�淶����IJ���
                _writestate.Name = "writeopc";//����
                _writestate.ServerHandle = null;//���������������ľ����
                _writestate.ClientHandle = Guid.NewGuid().ToString();//�ͻ��˸��������ľ����
                _writestate.Active = true;//������顣
                _writestate.UpdateRate = 50;//ˢ��Ƶ��Ϊ100���롣
                _writestate.Deadband = 0;// ����ֵ����Ϊ0ʱ���������˸������κ����ݱ仯��֪ͨ�顣
                _writestate.Locale = null;//�����õ���ֵ��
                //�������
                _writeSubscription = (Opc.Da.Subscription)m_server.CreateSubscription(_writestate);//�������
                
                //�趨��ʱ����״̬
                _tempstate = new Opc.Da.SubscriptionState();//�飨�����ߣ�״̬���൱��OPC�淶����IJ���
                _tempstate.Name = "opctemp";//����
                _tempstate.ServerHandle = null;//���������������ľ����
                _tempstate.ClientHandle = Guid.NewGuid().ToString();//�ͻ��˸��������ľ����
                _tempstate.Active = true;//������顣
                _tempstate.UpdateRate = 50;//ˢ��Ƶ��Ϊ100���롣
                _tempstate.Deadband = 0;// ����ֵ����Ϊ0ʱ���������˸������κ����ݱ仯��֪ͨ�顣
                _tempstate.Locale = null;//�����õ���ֵ��
                //�������
                _tempSubscription = (Opc.Da.Subscription)m_server.CreateSubscription(_tempstate);//�������
                
            }
            catch (Exception ex)
            {
                //if ((m_server == null) || (m_server.IsConnected == false))
                //{
                _IfConnectOPCServer = false;
                //}
                _opcError = "����OPC��ʱ��" + ex.Message;
                return ;
            }
        }
        /// <summary>
        /// ����OPC�飨�����ߣ����������ڱ�������
        /// </summary>
        /// <param name="plcConnectionID">��̬�����ж����ÿ��PLC���ӵı�ʶ</param>
        /// <param name="groupname">OPC�飨�����ߣ�����</param>
        /// <param name="itemnames">ָ���������б�������,�����ֵ����"DB1,INT1"</param>
        /// <returns></returns>
        public static Opc.Da.Subscription CreateItemGroup(string plcConnectionID,string groupname, string[] itemnames)
        {
            string[] itemName;
            //����item�б�
            Item[] items;
            ItemResult[] irs;
            try
            {
                if (_IfConnectOPCServer == false)
                {
                    if (ConnectOPCServer(_hostname, _progID) == false) return null;
                }
                //�趨��״̬
                state = new Opc.Da.SubscriptionState();//�飨�����ߣ�״̬���൱��OPC�淶����IJ���
                state.Name = groupname;//����
                state.ServerHandle = null;//���������������ľ����
                state.ClientHandle = Guid.NewGuid().ToString();//�ͻ��˸��������ľ����
                state.Active = true;//������顣
                state.UpdateRate = 50;//ˢ��Ƶ��Ϊ100���롣
                state.Deadband = 0;// ����ֵ����Ϊ0ʱ���������˸������κ����ݱ仯��֪ͨ�顣
                state.Locale = null;//�����õ���ֵ��


                //������
                subscription = (Opc.Da.Subscription)m_server.CreateSubscription(state);//������

                //����Item�б�
                //��Ӧ����Ϊ:{Byte,Byte,Char,Short,String,Word,Boolean}
                itemName = itemnames;//{ "S7:[S7 connection_1]DB1,INT1", "S7:[@LOCALSERVER]DB1,INT20", "S7:[@LOCALSERVER]DB1,INT30", "S7:[@LOCALSERVER]DB1,INT50" };

                //����item�б�
                items = new Item[itemName.Length];//�����������item
                int i;
                for (i = 0; i < items.Length; i++)//item��ʼ����ֵ
                {
                    items[i] = new Item();//����һ����Item����
                    items[i].ClientHandle = Guid.NewGuid().ToString();//�ͻ��˸������������ľ����
                    items[i].ItemPath = null; //���������ڷ������е�·����
                    items[i].ItemName = plcConnectionID + itemName[i]; //���������ڷ������е����֡�
                }

                //����Item
                irs = subscription.AddItems(items);
                return subscription;
            }
            catch (Exception ex)
            {
                //if ((m_server == null) || (m_server.IsConnected == false))
                //{
                _IfConnectOPCServer = false;
                //}
                _opcError = "����OPC��ʱ��" + ex.Message;
                return null;
            }
            finally
            {
                itemName=null;
                //����item�б�
                items=null;
                irs=null;
            }
        }
        
        /// <summary>
        /// ͬ����ȡȫ��OPC���ڱ�����ֵ��List��������+ ":" +����ֵ��
       /// </summary>
       /// <param name="subscription">OPC������</param>
       /// <returns></returns>
        public static List<string> SyncReadAllItems(Opc.Da.Subscription subscription)
        {
            ItemValueResult[] values;
            List<string> itemnamevalue;
            try
            {
                if (_IfConnectOPCServer == false)
                {
                    if (ConnectOPCServer(_hostname, _progID) == false) return null;
                }
                itemnamevalue = new List<string>();
                //ע��ص��¼�
                //subscription.DataChanged += new Opc.Da.DataChangedEventHandler(OnDataChange);

                //���²���ͬ����
                //���¶�������
                values = subscription.Read(subscription.Items);
                foreach (ItemValueResult value in values)
                {
                    itemnamevalue.Add(value.ItemName + ":" + value.Value);
                    
                }
                //subscription.RemoveItems(subscription.Items);
                //subscription.Dispose();
                return itemnamevalue;
            }
            catch (Exception ex)
            {
                //if ((m_server == null) || (m_server.IsConnected == false))
                //{
                _IfConnectOPCServer = false;
                //}
                _opcError = "ͬ��������ʱ��" + ex.Message;
                return null;
            }
            finally
            {
                values=null;
                itemnamevalue=null;
            }
        }

        /// <summary>
        /// ��ȡָ��S7Connection����DB1��Ӧ��ǩ��������ݣ�����ֵ������ǩֵ����ɵ�����
        /// </summary>
        /// <param name="S7Connection">OPC����</param>
        /// <returns></returns>
        public static byte[] SyncReadAllItems(string S7Connection)
        {//20110216
            ItemValueResult[] values;
            byte[] itemnamevalue;
            try
            {
                if (_IfConnectOPCServer == false)
                {
                    if (ConnectOPCServer(_hostname, _progID) == false) return null;
                }
                if (_readSubscription.Items != null)
                {
                    _readSubscription.RemoveItems(_readSubscription.Items);
                }
                string[] itemName= new string[1];
                DataView dv = dbo.ExceSQL("SELECT F_DBW2Address,F_DBWGetLength  FROM T_Base_Device WHERE (F_DeviceKindIndex = 28 and F_S7Connection='"+S7Connection+"')").Tables[0].DefaultView;
                if (dv.Count > 0)
                {
                    
                    itemName[0] = S7Connection + Model.CGeneralFunction.DBGet + ",byte"+ dv[0]["F_DBW2Address"].ToString() + "," + (System.Convert.ToInt32( dv[0]["F_DBWGetLength"])).ToString();
                    //20110726
                }
                else
                {
                    return null ;
                }
                
                //�����item�б�
                Item[] items = new Item[itemName.Length];//�����������item
                int i;
                for (i = 0; i < items.Length; i++)//item��ʼ����ֵ
                {
                    items[i] = new Item();//����һ����Item����
                    items[i].ClientHandle = Guid.NewGuid().ToString();//�ͻ��˸������������ľ����
                    items[i].ItemPath = null; //���������ڷ������е�·����
                    items[i].ItemName = itemName[i]; //���������ڷ������е����֡�
                }

                //���Ӷ�Item
                
                ItemResult[] irs = _readSubscription.AddItems(items);
                //_plcStates = new int[System.Convert.ToInt32(devinfo28.Dbw2Getlength)];
                //_readSubscription.DataChanged += new Opc.Da.DataChangedEventHandler(OnDataChange);
                if (ConnectCount.ContainsKey(S7Connection) == false)//20110726
                {
                    ConnectCount.Add(S7Connection, 0);
                }
                if (ConnectCount[S7Connection] > 1)//20110726
                {

                    _opcError = "ͬ������ʱ��OPC Serverû���ӵ�PLC�����ҳ����ظ����Ӵ���!���ȹر�����أ����ͨѶ��·��ȷ�Ϻ����´�����أ�";
                    return null;
                }
                values = _readSubscription.Read(_readSubscription.Items);
                if (values.Length <= 0)
                {
                    ConnectCount[S7Connection]++;//20110726
                    _opcError = "ͬ��������ʱ��OPC Serverû���ӵ�PLC!";
                    return null;
                }
                if (values[0].Quality == Quality.Bad)
                {
                    ConnectCount[S7Connection]++;//20110726
                    _opcError = "ͬ��������ʱ��OPC Serverû���ӵ�PLC!";
                    return null;
                }
                
                Array arr = (Array)values[0].Value;
                itemnamevalue = new byte[arr.GetLength(0)];
                Array.Copy(arr, itemnamevalue, arr.GetLength(0));
                _readSubscription.RemoveItems(_readSubscription.Items);
                //subscription.Dispose();
                return itemnamevalue;
            }
            catch (Exception ex)
            {
                //if ((m_server == null) || (m_server.IsConnected == false))
                //{
                _IfConnectOPCServer = false;
                //}
                _opcError = "ͬ��������ʱ��" + ex.Message;
                return null;
            }
            finally
            {
                itemnamevalue = null;
                values = null;
            }
        }

        /// <summary>
        /// ��ȡָ����ǩ���Ƶ�����
        /// </summary>
        /// <param name="itemname">��ǩ����</param>
        /// <returns></returns>
        public static string SyncReadItemValue(string itemname)
        {
            string[] items = new string[1] { itemname };
            Subscription subs = CreateItemGroup(_PLCconnectionID, Guid.NewGuid().ToString(), items);
            string itemnamevalue = "";
            ItemValueResult[] values = subs.Read(subs.Items);
            try
            {
                if (_IfConnectOPCServer == false)
                {
                    if (ConnectOPCServer(_hostname, _progID) == false) return null;
                }

                if (values.Length > 0)
                {
                    if (values[0].Value != null)
                    {
                        itemnamevalue = values[0].Value.ToString();
                    }
                }
                subs.RemoveItems(subs.Items);
                subs.Dispose();
                return itemnamevalue;
            }
            catch (Exception ex)
            {
                //if ((m_server == null) || (m_server.IsConnected == false))
                //{
                _IfConnectOPCServer = false;
                //}
                _opcError = "ͬ��������ʱ��" + ex.Message;
                return null;
            }
            finally
            {
                items = null;
                subs = null;
                itemnamevalue = null;
                values = null;
            }
        }

        //20100221
        #region �Ӽ�ͬ������дOPC

        /// <summary>
        /// �Ӽ���ȡ����_readSubscription�������
        /// </summary>
        /// <returns></returns>
        //public static byte[] SyncReadAllItems()
        //{
        //    ItemValueResult[] values;
        //    byte[] itemnamevalue;
        //    try
        //    {
        //        if (_IfConnectOPCServer == false)
        //        {
        //            if (ConnectOPCServer(_hostname, _progID) == false) return null;
        //        }
        //        //List<string> itemnamevalue = new List<string>();
        //        //ע��ص��¼�
        //        //subscription.DataChanged += new Opc.Da.DataChangedEventHandler(OnDataChange);

        //        //���²���ͬ����
        //        //���¶�������
        //        if (ConnectCount > 1)
        //        {
        //            _opcError = "ͬ������ʱ��OPC Serverû���ӵ�PLC�����ҳ����ظ����Ӵ���!���ȹر�����أ����ͨѶ��·��ȷ�Ϻ����´�����أ�";
        //            return null;
        //        }
        //        values = _readSubscription.Read(_readSubscription.Items);
        //        if (values.Length <= 0)
        //        {
        //            _opcError = "ͬ��������ʱ��OPC Serverû���ӵ�PLC!";
        //            return null;
        //        }
        //        if (values[0].Quality == Quality.Bad)
        //        {
        //            ConnectCount++;
        //            _opcError = "ͬ��������ʱ��OPC Serverû���ӵ�PLC!";
        //            return null;
        //        }
        //        Array arr = (Array)values[0].Value;
        //        itemnamevalue = new byte[arr.GetLength(0)];
        //        Array.Copy(arr, itemnamevalue, arr.GetLength(0));
        //        //subscription.RemoveItems(subscription.Items);
        //        //subscription.Dispose();
        //        return itemnamevalue;
        //    }
        //    catch (Exception ex)
        //    {
        //        //if ((m_server == null) || (m_server.IsConnected == false))
        //        //{
        //        _IfConnectOPCServer = false;
        //        //}
        //        _opcError = "ͬ��������ʱ��" + ex.Message;
        //        return null;
        //    }
        //    finally
        //    {
        //        itemnamevalue = null;
        //        values = null;
        //    }
        //}
        /// <summary>
        /// �Ӽ���ָ��OPC��ǩ��д�����ݣ�_writeSubscription�飩
        /// </summary>
        /// <param name="itemnames"></param>
        /// <param name="itemvalue"></param>
        /// <returns></returns>
        public static bool SyncWriteAllItemValue(string[] itemnames, string[] itemvalue)
        {
            Item[] items;
            ItemValue[] itemvalues;
            IdentifiedResult[] ir;
            try
            {
                if (_IfConnectOPCServer == false)
                {
                    if (ConnectOPCServer(_hostname, _progID) == false) return false;
                }
                if (ConnectCount.ContainsKey(_PLCconnectionID) == false)//20110726
                {
                    ConnectCount.Add(_PLCconnectionID, 0);
                }
                if (ConnectCount[_PLCconnectionID] > 1)//20110726
                {
                    ConnectCount[_PLCconnectionID]++;//20110726
                    _opcError = "ͬ������ʱ��OPC Serverû���ӵ�PLC�����ҳ����ظ����Ӵ���!���ȹر�����أ����ͨѶ��·��ȷ�Ϻ����´�����أ�";
                    return false;
                }
                //����item�б�
                items = new Item[itemnames.Length];//�����������item
                int i;
                for (i = 0; i < items.Length; i++)//item��ʼ����ֵ
                {
                    items[i] = new Item();//����һ����Item����
                    items[i].ClientHandle = Guid.NewGuid().ToString();//�ͻ��˸������������ľ����
                    items[i].ItemPath = null; //���������ڷ������е�·����
                    items[i].ItemName = _PLCconnectionID + itemnames[i]; //���������ڷ������е����֡�
                }
                _writeSubscription.AddItems(items);
                itemvalues = new ItemValue[_writeSubscription.Items.Length];
                for (int ii = 0; ii < _writeSubscription.Items.Length; ii++)
                {
                    itemvalues[ii] = new ItemValue((ItemIdentifier)_writeSubscription.Items[ii]);
                    itemvalues[ii].Value = itemvalue[ii];
                }

                ir = _writeSubscription.Write(itemvalues);

                _writeSubscription.RemoveItems(_writeSubscription.Items);
                //_writeSubscription.Dispose();
                //GC.Collect();
                return true;
            }
            catch (Exception ex)
            {
                //if ((m_server == null) || (m_server.IsConnected == false))
                //{
                _IfConnectOPCServer = false;
                //}
                _opcError = "ͬ��д����ʱ��" + ex.Message;
                return false;
            }
            finally
            {
                items=null;
                itemvalues=null;
                ir=null;
            }
        }

        public static bool SyncWriteAllItemValue(StringBuilder[] itemnames, StringBuilder[] itemvalue)
        {
            Item[] items;
            ItemValue[] itemvalues;
            IdentifiedResult[] ir;
            try
            {

                if (_IfConnectOPCServer == false)
                {
                    if (ConnectOPCServer(_hostname, _progID) == false) return false;
                }
                if (ConnectCount.ContainsKey(_PLCconnectionID) == false)//20110726
                {
                    ConnectCount.Add(_PLCconnectionID, 0);
                }
                if (ConnectCount[_PLCconnectionID] > 1)//20110726
                {
                    ConnectCount[_PLCconnectionID]++;//20110726
                    //_opcError = "ͬ������ʱ��OPC Serverû���ӵ�PLC:"+_PLCconnectionID.ToString()+"���˹�ȷ�Ϻ���С��豸��ʼ����";
                    return false;
                }
                //����item�б�
                items = new Item[itemnames.Length];//�����������item
                int i;
                for (i = 0; i < items.Length; i++)//item��ʼ����ֵ
                {
                    items[i] = new Item();//����һ����Item����
                    items[i].ClientHandle = Guid.NewGuid().ToString();//�ͻ��˸������������ľ����
                    items[i].ItemPath = null; //���������ڷ������е�·����
                    items[i].ItemName = _PLCconnectionID + itemnames[i].ToString(); //���������ڷ������е����֡�
                }
                _writeSubscription.AddItems(items);
                itemvalues = new ItemValue[_writeSubscription.Items.Length];
                for (int ii = 0; ii < _writeSubscription.Items.Length; ii++)
                {
                    itemvalues[ii] = new ItemValue((ItemIdentifier)_writeSubscription.Items[ii]);
                    itemvalues[ii].Value = itemvalue[ii].ToString();
                }

                ir = _writeSubscription.Write(itemvalues);
                
                _writeSubscription.RemoveItems(_writeSubscription.Items);
                if (ir.Length == 0)
                {
                    ConnectCount[_PLCconnectionID]++;//20120405
                    _opcError = "ͬ��д����ʱ��OPC Serverû���ӵ�PLC��"+_PLCconnectionID.ToString();
                    return false;
                }
                else
                {
                    if (ir[0].ResultID !=ResultID.S_OK)
                    {
                        ConnectCount[_PLCconnectionID]++;//20120405
                        _opcError = "ͬ��д����ʱ��OPC Serverû���ӵ�PLC��"+_PLCconnectionID.ToString();
                        return false;
                    }
                    else
                    {
                        return true;
                    }
                }
                //_writeSubscription.Dispose();
                //GC.Collect();
                
            }
            catch (Exception ex)
            {
                //if ((m_server == null) || (m_server.IsConnected == false))
                //{
                _IfConnectOPCServer = false;
                //}
                _opcError = "ͬ��д����ʱ��" + ex.Message;
                return false;
            }
            finally
            {
                items = null;
                itemvalues = null;
                ir = null;
            }
        }
        /// <summary>
        /// �Ӽ���ȡָ��OPC��ǩ�����ݣ�_tempSubscription�飩
        /// </summary>
        /// <param name="itemnames"></param>
        /// <returns></returns>
        public static object[] SyncReadItemValues(string[] itemnames)
        {
            Item[] items;
            ItemResult[] irs;
            ItemValueResult[] values;
            object[] itemnamevalue;
            try
            {
                string ss; string ss1;
                ss = DateTime.Now.Second.ToString() + "-" + DateTime.Now.Millisecond.ToString();
                if (_IfConnectOPCServer == false)
                {
                    if (ConnectOPCServer(_hostname, _progID) == false) return null;
                }
                //����item�б�
                items = new Item[itemnames.Length];//�����������item
                int i;
                for (i = 0; i < items.Length; i++)//item��ʼ����ֵ
                {
                    items[i] = new Item();//����һ����Item����
                    items[i].ClientHandle = Guid.NewGuid().ToString();//�ͻ��˸������������ľ����
                    items[i].ItemPath = null; //���������ڷ������е�·����
                    items[i].ItemName = _PLCconnectionID + itemnames[i]; //���������ڷ������е����֡�
                }
                irs = _tempSubscription.AddItems(items);

                values = _tempSubscription.Read(_tempSubscription.Items);
                if (values[0].Quality == Quality.Bad)
                {
                    _opcError = "ͬ��������ʱ��OPC Serverû���ӵ�PLC!";
                    return null;
                }
                itemnamevalue = new object[values.Length];
                int k = 0;
                foreach (ItemValueResult value in values)
                {
                    itemnamevalue[k] = value.Value;
                    k++;
                }
                //Array.Copy(values.[0].Value, itemnamevalue, values.Length);
                _tempSubscription.RemoveItems(_tempSubscription.Items);
                //_tempSubscription.Dispose();
                //GC.Collect();
                ss1 = DateTime.Now.Second.ToString() + "-" + DateTime.Now.Millisecond.ToString();
                return itemnamevalue;
            }
            catch (Exception ex)
            {
                //if ((m_server == null) || (m_server.IsConnected == false))
                //{
                _IfConnectOPCServer = false;
                //}
                _opcError = "ͬ��������ʱ��" + ex.Message;
                return null;
            }
            finally
            {
                items=null ;
                irs=null ;
                values=null ;
                itemnamevalue=null ;
            }
        }
        #endregion


        //20100221
        //#region �Ӽ�ͬ��д���첽��OPC
        //static byte[] AsyncReadAllItemNameValue= new byte[(int)devinfo28.Dbw2Getlength];
        //static bool AsyncReadOK=false ;
        ///// <summary>
        ///// �Ӽ��첽��ȡ����_readSubscription�������
        ///// </summary>
        ///// <returns></returns>
        //public static void AsyncReadAllItems()
        //{
            
        //    try
        //    {
        //        if (_IfConnectOPCServer == false)
        //        {
        //            if (ConnectOPCServer(_hostname, _progID) == false) return ;
        //        }
                
        //        IRequest quest=null ;
        //        _readSubscription.Read(_readSubscription.Items, Guid.NewGuid().ToString(), OnReadComplete,out quest);
                
        //    }
        //    catch (Exception ex)
        //    {
        //        //if ((m_server == null) || (m_server.IsConnected == false))
        //        //{
        //        _IfConnectOPCServer = false;
        //        //}
        //        _opcError = "�첽������ʱ��" + ex.Message;
        //        AsyncReadOK = false;
        //        return ;
        //    }
        //    finally
        //    {
                
        //    }
        //}
        ///// <summary>
        ///// �Ӽ���ָ��OPC��ǩ��ͬ��д�����ݣ�_writeSubscription�飩
        ///// </summary>
        ///// <param name="itemnames"></param>
        ///// <param name="itemvalue"></param>
        ///// <returns></returns>
        //public static bool SyncWriteGroupItemValue(string[] itemnames, string[] itemvalue)
        //{
        //    Item[] items;
        //    ItemValue[] itemvalues;
        //    IdentifiedResult[] ir;
        //    try
        //    {
        //        if (AsyncReadOK == false) return false;
        //        if (_IfConnectOPCServer == false)
        //        {
        //            if (ConnectOPCServer(_hostname, _progID) == false) return false;
        //        }
        //        //����item�б�
        //        items = new Item[itemnames.Length];//�����������item
        //        int i;
        //        for (i = 0; i < items.Length; i++)//item��ʼ����ֵ
        //        {
        //            items[i] = new Item();//����һ����Item����
        //            items[i].ClientHandle = Guid.NewGuid().ToString();//�ͻ��˸������������ľ����
        //            items[i].ItemPath = null; //���������ڷ������е�·����
        //            items[i].ItemName = _PLCconnectionID + itemnames[i]; //���������ڷ������е����֡�
        //        }
        //        _writeSubscription.AddItems(items);
        //        itemvalues = new ItemValue[_writeSubscription.Items.Length];
        //        for (int ii = 0; ii < _writeSubscription.Items.Length; ii++)
        //        {
        //            itemvalues[ii] = new ItemValue((ItemIdentifier)_writeSubscription.Items[ii]);
        //            itemvalues[ii].Value = itemvalue[ii];
        //        }

        //        ir = _writeSubscription.Write(itemvalues);

        //        _writeSubscription.RemoveItems(_writeSubscription.Items);
        //        //_writeSubscription.Dispose();
        //        GC.Collect();
        //        return true;
        //    }
        //    catch (Exception ex)
        //    {
        //        //if ((m_server == null) || (m_server.IsConnected == false))
        //        //{
        //        _IfConnectOPCServer = false;
        //        //}
        //        _opcError = "ͬ��д����ʱ��" + ex.Message;
        //        return false;
        //    }
        //    finally
        //    {
        //        items = null;
        //        itemvalues = null;
        //        ir = null;
        //    }
        //}
        ////ReadComplete�ص�
        //public static void OnReadComplete(object requestHandle, Opc.Da.ItemValueResult[] values)
        //{
        //    /*Console.WriteLine("�����첽��name:{0},value:{1}", values[0].ItemName, values[0].Value);
        //    if ((int)requestHandle == 1)
        //        Console.WriteLine("�¼��źž��Ϊ{0}", requestHandle);*/
        //    //�������������ˣ�ֱ�ӽ���OPC����
        //    try
        //    {
        //        if (values.Length <= 0)
        //        {
        //            _opcError = "�첽������ʱ��OPC Serverû���ӵ�PLC!";
        //            AsyncReadOK = false;
        //            return ;
        //        }
        //        if (values[0].Quality == Quality.Bad)
        //        {
        //            _opcError = "�첽������ʱ��OPC Serverû���ӵ�PLC!";
        //            AsyncReadOK = false;
        //            return ;
        //        }


        //        Array.Copy((Array)values[0].Value, AsyncReadAllItemNameValue, AsyncReadAllItemNameValue.GetLength(0));// (int)devinfo28.Dbw2Getlength
        //        AsyncReadOK = true;
        //    }
        //    catch (Exception ex)
        //    {
        //        _opcError = "�첽������ʱ��"+ex.Message ;
        //        AsyncReadOK = false;
        //        return;
        //    }
        //    finally
        //    {
        //        values = null;
        //    }
        //}
        //#endregion



        /// <summary>
        /// ����豸��������
        /// </summary>
        /// <param name="devIdx">�豸����</param>
        /// <returns>�豸��������</returns>
        static int GetDeviceKindIdx(int devIdx)
        {
            System.Object lockThis = new System.Object();
            lock (lockThis)
            {
                try
                {

                    DataView dv= dbo.ExceSQL(string.Format("SELECT F_DeviceKindIndex FROM T_Base_Device WHERE F_DeviceIndex={0}", devIdx)).Tables[0].DefaultView;
                    if (dv.Count > 0)
                    {
                        return System.Convert.ToInt32(dv[0]["F_DeviceKindIndex"]);
                    }
                    else
                        return 0;
                }
                catch (Exception ex)
                {
                    throw ex;
                }
            }
        }
        public static void DisConnectOPCServer()
        {
            if (m_server== null) return;
            if (m_server.IsConnected == false ) return;

            
            foreach (Subscription sub in SubscriptionGroup)
            {
                try
                {
                    m_server.CancelSubscription(sub);//m_serverǰ����˵����֪ͨ������Ҫ��ɾ���顣     
                }
                catch
                {

                }
                sub.Dispose();//ǿ��.NET��Դ����վ���ո�subscription��������Դ��
            }
            if (_readSubscription != null)
            {
                m_server.CancelSubscription(_readSubscription);//m_serverǰ����˵����֪ͨ������Ҫ��ɾ���顣        
                _readSubscription.Dispose();//ǿ��.NET��Դ����վ���ո�subscription��������Դ��
            }
            
            if (_writeSubscription != null)
            {
                m_server.CancelSubscription(_writeSubscription);//m_serverǰ����˵����֪ͨ������Ҫ��ɾ���顣        
                _writeSubscription.Dispose();//ǿ��.NET��Դ����վ���ո�subscription��������Դ��
            }
            m_server.Disconnect();//
        }
        public static void  CreateReadSubscription()
        {
            if (_IfConnectOPCServer == false)
            {
                if (ConnectOPCServer(_hostname, _progID) == false) return;
            }
            #region ������ȫ����ǩ��
            Opc.Da.SubscriptionState _readstate = null;//�����飨�����ߣ�״̬���൱��OPC�淶����IJ���
            //�趨��ȡ��״̬
            _readstate = new Opc.Da.SubscriptionState();//�飨�����ߣ�״̬���൱��OPC�淶����IJ���
            _readstate.Name = "readopc";//����
            _readstate.ServerHandle = null;//���������������ľ����
            _readstate.ClientHandle = Guid.NewGuid().ToString();//�ͻ��˸��������ľ����
            _readstate.Active = true;//������顣
            _readstate.UpdateRate = 50;//ˢ��Ƶ��Ϊ100���롣
            _readstate.Deadband = 0;// ����ֵ����Ϊ0ʱ���������˸������κ����ݱ仯��֪ͨ�顣
            _readstate.Locale = null;//�����õ���ֵ��
            //���Ӷ���
            _readSubscription = (Opc.Da.Subscription)m_server.CreateSubscription(_readstate);//������ȡ��
           
            #endregion
        }
    }
}