zoukankan      html  css  js  c++  java
  • 对“xxx”类型的已垃圾回收委托进行了回调。这可能会导致应用程序崩溃、损坏和数据丢失。向非托管代码传递委托时,托管应用程序必须让这些委托保持活动状态,直到确信不会再次调用它们。 错误解决一例。

    最近在写一个海康的门禁的自动监控刷卡事件的程序。

    因为用c#写的,大家都知道c#是垃圾自动回收的。海康提供的api是用c++写的,要将处理的回调代码委托给api 。刚开始的时候很顺利,但当运行一段时间就会报以下错误:

    对“xxx”类型的已垃圾回收委托进行了回调。这可能会导致应用程序崩溃、损坏和数据丢失。向非托管代码传递委托时,托管应用程序必须让这些委托保持活动状态,直到确信不会再次调用它们。 

    大致的原因是:c#把回调函数资源回收了,导致api收到事件的时候执行回调出错。

    网上的解决方案是将回调方法写成static的(静态方法)。但我这里不行。

    最后还是微软官方的解决方法可靠: 

    除了设置成static的还要在代码后加:GC.KeepAlive(dev);

            public static void MsgCallback(int lCommand, ref CHCNetSDK.NET_DVR_ALARMER pAlarmer, IntPtr pAlarmInfo, uint dwBufLen, IntPtr pUser)
            {
                try
                {
                    switch (lCommand)
                    {
                        case CHCNetSDK.COMM_ALARM_ACS:
                            ProcessCommAlarmACS(ref pAlarmer, pAlarmInfo, dwBufLen, pUser);
                            break;
                        default:
                            break;
                    }
                }
                catch (System.Exception ex)
                {
                    Program.WriteLog(0, "处理事件报错:" + ex);
                }
    
    
            }
    

      

            private void StartRead()
            {
                Program.LocalWriteLog("进入StartRead...........");
                zd.zd api = new zd.zd();
                 for (int i = 0; i < _listDoors.Count; i++)
                    {
                        Door d = _listDoors[i];
                        if (!d.isLogon)
                        {
                            CHCNetSDK.NET_DVR_USER_LOGIN_INFO loginInfo = new CHCNetSDK.NET_DVR_USER_LOGIN_INFO();
                            loginInfo.wPort = Convert.ToUInt16(d.cPort);
                            loginInfo.sDeviceAddress = d.cIP;
                            loginInfo.sUserName = d.cLoginUser;
                            loginInfo.sPassword = d.cLoginPassword;
                            try
                            {
                                switch (i)
                                {
                                    case 0:
                                        this._arLoginDevices[i] = new Device00(loginInfo);
                                        break;
                                    case 1:
                                        this._arLoginDevices[i] = new Device01(loginInfo);
                                        break;
                                    case 2:
                                        this._arLoginDevices[i] = new Device02(loginInfo);
                                        break;
                                    case 3:
                                        this._arLoginDevices[i] = new Device03(loginInfo);
                                        break;
                                    case 4:
                                        this._arLoginDevices[i] = new Device04(loginInfo);
                                        break;
                                    case 5:
                                        this._arLoginDevices[i] = new Device05(loginInfo);
                                        break;
                                    case 6:
                                        this._arLoginDevices[i] = new Device06(loginInfo);
                                        break;
                                    case 7:
                                        this._arLoginDevices[i] = new Device07(loginInfo);
                                        break;
                                    case 8:
                                        this._arLoginDevices[i] = new Device08(loginInfo);
                                        break;
                                    default:
                                        this._arLoginDevices[i] = new Device09(loginInfo);
                                        break;
                                }
                                
                                //this.listGch.Add(GCHandle.Alloc(this._arLoginDevices[i]));
                                Program.LocalWriteLog("加入设备:" + loginInfo.sDeviceAddress);
                            }
                            catch (System.Exception ex)
                            {
                                string cMsg = "加入设备出错:IP," + loginInfo.sDeviceAddress + ",信息:" + ex.Message;
                                Program.LocalWriteLog(cMsg);
                                api.AddLog(_key,0,cMsg);
                            }
                        }
                    }
                 int j=0;
                 while (true)
                 {
                     foreach (var dev in this._arLoginDevices)
                     {
                         if (dev == null)
                         {
                             continue;
                         }
                         if (!dev.IsLogin)
                         {
                             try
                             {
                                 dev.Login();
                             }
                             catch (System.Exception ex)
                             {
                                 string cMsg = "登录设备出错:IP," + dev.DeviceLoginInfo.sDeviceAddress + ",信息:" + ex.Message;
                                 Program.LocalWriteLog(cMsg);
                                 api.AddLog(_key, 0, cMsg);
                             }
    
                         }
                         if (dev.IsLogin && !dev.IsGuard)
                         {
                             try
                             {
                                 dev.Guard();
                             }
                             catch (System.Exception ex)
                             {
                                 string cMsg = "监控设备出错:IP," + dev.DeviceLoginInfo.sDeviceAddress + ",信息:" + ex.Message;
                                 Program.LocalWriteLog(cMsg);
                                 api.AddLog(_key, 0, cMsg);
                             }
                         }
                         GC.KeepAlive(dev);
                     }
                     System.Threading.Thread.Sleep(5 * 1000);
                 }
    
                 Program.LocalWriteLog("正常退出");
                    
            }
    

      

  • 相关阅读:
    C#0004--打开和保存文本文件
    C#0003--如何使用树状视图控件
    C#0002--信息提示框的使用
    C#0001--如何使用错误提醒控件
    使用C#创建简单的联系人备忘录
    SharePoint站点图片轮转器imageRotator
    优秀的代码的设计和组织架构
    思考:为什么每一种开发语言的语法都是不一样的呢(语法设置的不一样的出发点是基于什么考虑)?如果设置成一样有什么不可行的吗?
    分析一个突发问题的思考方法
    思考:架构师的前瞻性能力
  • 原文地址:https://www.cnblogs.com/KevinMO/p/11660708.html
Copyright © 2011-2022 走看看