精华内容
下载资源
问答
  • 接下来就是要进行更为精准更智能追踪。因此,在接下来的代码演示Demo中我重新设计了几个,一个是PlayObject,这个其实也没有什么新的东西,都是之前已经介绍过的,无非就是速度向量、位置以及移动控制等它的...

    CSDN个人博客地址,凯尔八阿哥栏http://blog.csdn.net/zhangxiao13627093203,转载请注明出处

    接下来就是要进行更为精准更智能的追踪。因此,在接下来的代码演示Demo中我重新设计了几个类,一个是PlayObject,这个类其实也没有什么新的东西,都是之前已经介绍过的,无非就是速度向量、位置以及移动控制等它的代码设计如下:

    </pre><span style="font-size:24px"></span><pre name="code" class="csharp">using UnityEngine;
    using System.Collections;
    
    public class PlayObject : MonoBehaviour
    {
        [HideInInspector]
        public float moveVx;//x方向的分速度
        [HideInInspector]
        public float moveVy;//y方向的分速度
        /// <summary>
        /// 2维坐标(x,y)
        /// </summary>
        public Vector2 Position
        {
            get
            {
                return new Vector2(this.transform.position.x, this.transform.position.y);
            }
        }
        private Vector2 _vHeading;
        /// <summary>
        /// //设置导弹的前进方向的归一化向量m_vHeading
        /// </summary>
        public Vector2 vHeading
        {
            get
            {
                float length = Mathf.Sqrt(moveVx * moveVx + moveVy * moveVy);
                if (length != 0)
                {
                    _vHeading.x = moveVx / length;
                    _vHeading.y = moveVy / length;
                }
                return _vHeading;
            }
        }
        private Vector2 _vSide;
        /// <summary>
        /// 前进方向的垂直向量
        /// </summary>
        public Vector2 vSide
        {
            get
            {
                _vSide.x = -vHeading.y;
                _vSide.y = vHeading.x;
                return _vSide;
            }
        }
    
        /// <summary>
        /// 速度向量
        /// </summary>
        public Vector2 Velocity
        {
            get
            {
                return new Vector2(moveVx, moveVy);
            }
        }
        /// <summary>
        /// 速度标量
        /// </summary>
        public float Speed
        {
            get
            {
                return Mathf.Sqrt(moveVx * moveVx + moveVy * moveVy);
            }
        }
        public float MaxSpeedRate;
        // Use this for initialization
        void Start()
        {
    
    
        }
    
        // Update is called once per frame
        void Update()
        {
    
        }
        /// <summary>
        /// 移动物体
        /// </summary>
        /// <param name="speedRate">移动的速度率,一般为1</param>
        /// <param name="isLookAtVelocityVector">是否要这是速度矢量与物体的朝向一致</param>
        public void Move(float speedRate, bool isLookAtVelocityVector)
        {
            this.transform.position += new Vector3(moveVx * Time.deltaTime, moveVy * Time.deltaTime, 0) * speedRate;
            //  Debug.Log("x:" + m_postion.x + "y:" + m_postion.y);
            //调整导弹的朝向是的它和速度矢量合成方向一样
            if (isLookAtVelocityVector)
            {
                LookAtVelocityVector();
            }
        }
        /// <summary>
        /// 使得物体始终朝向矢量速度的方向
        /// </summary>
        void LookAtVelocityVector()
        {
            float zAngles = Mathf.Atan(moveVx / moveVy) * (-180 / Mathf.PI);
            if (moveVy == 0)
            {
                zAngles = moveVx > 0 ? -90 : 90;
                //跟以往的计算角度不同的是,这里加了moveVx==0的独立判断,这样可以在不控制的时候保持原状态
                if (moveVx == 0)
                {
                    zAngles = this.transform.rotation.eulerAngles.z;
                }
            }
    
            if (moveVy < 0)
            {
                zAngles = zAngles - 180;
            }
            Vector3 tempAngles = new Vector3(0, 0, zAngles);
            Quaternion tempQua = this.transform.rotation;
            tempQua.eulerAngles = tempAngles;
            this.transform.rotation = tempQua;
        }
    }
    


    
    

    这样就可以很方便的操作我们的控制对象,作为使用例子我写了一个鼠标点击追踪算法,效果如图所示

    它的核心代码如下:

    <span style="font-size:24px;">using UnityEngine;
    using System.Collections;
    using UnityEngine.UI;
    
    public class AISeek : MonoBehaviour {
        public PlayObject plane;
        public Image Aim;
        public float vecChangeRate;//这个数值越大在目标点的穿梭次数就会越多,一般为1
        public float MaxSpeed;
        public float FleeDistance;
        Vector2 AimPos;
    	// Use this for initialization
    	void Start () {
            AimPos = new Vector2(Aim.transform.position.x, Aim.transform.position.y);
    	
    	}
    	
    	// Update is called once per frame
        void Update()
        {
            if (Input.GetMouseButtonDown(0))
            {
                Aim.transform.position = Input.mousePosition;
                AimPos = new Vector2(Aim.transform.position.x, Aim.transform.position.y);
            }
            Vector2 moveVec = AI_Seek(AimPos);
            float length = Mathf.Sqrt(moveVec.x * moveVec.x + moveVec.y * moveVec.y);
            if (length != 0)
            {
                //   Debug.Log("x:" + moveVec.x + "y:" + moveVec.y);
                plane.moveVx += vecChangeRate * moveVec.x / length;
                plane.moveVy += vecChangeRate * moveVec.y / length;
    
            }
            plane.Move(1, true);
        }
        Vector2 AI_Seek(Vector2 targetPos)
        {
            Vector2 vSeekPos = targetPos - plane.Position;
            vSeekPos = vSeekPos.normalized*MaxSpeed - plane.Velocity;
            return vSeekPos;
        }
    }
    </span>

    它的原理是:首先计算预期的速度,这个速度是智能体在理想化情况下到达目标位置所需的速度,它是从智能体到目标的向量,大小为智能体的最大速度,该方法返回的操控力是所需要的力,当把它加到智能体当前速度向量上就得到预期的速度。所以,你可以简单的从预期速度中减去智能体的当前速度。但是你很快就会发现这个算法的一个问题,就是飞机在到达指定目标位置后并没有停止下来,而是反复的往返穿越目标点,如图所示:

    针对这个问题,我会在下一篇进行讲解,接下来要讲的还是和这个算法直接相关的东西,我必须要先把它讲完。

    有追踪算法,那么肯定也要有反追踪算法,其实它的原理在基于追踪的原理上就显得非常简单了

    <span style="font-size:24px;">   Vector2 AI_UNSeek(Vector2 targetPos)
        {
            Vector2 disPos = plane.Position - targetPos;
            float distance = Mathf.Sqrt(disPos.x * disPos.x + disPos.y * disPos.y);
            if(distance>FleeDistance)
            {
                return Vector2.zero;
            }
            disPos = disPos.normalized * MaxSpeed - plane.Velocity;
            return disPos;
        }</span>
    看看这个代码和上面的AI_Seek(vecter2 targetPos)有什么不一样。我在反追踪代码上面还加了一个距离的判断,也就是当目标和 飞机的距离小于预设的追踪距离的时候就开始追踪,它的效果图如图所示

    展开全文
  • 在上一节的基础上进行完善Enemy。 首先添加这些变量。 public float chaseSpeed = 6f;//追踪速度 public float chaseWaitTime = 5f;//追踪时间 private float chaseTimer = 0f;//已经追踪的时间 public float ...

    敌人攻击

    在上一节的基础上进行完善Enemy类。
    首先添加这些变量。

        public float chaseSpeed = 6f;//追踪速度
        public float chaseWaitTime = 5f;//追踪时间
        private float chaseTimer = 0f;//已经追踪的时间
        public float sqrPlayerDist = 4f;//与玩家的距离
        private bool chase = false;//是否追踪
        public float shootRotSpeed = 4f;//视角的旋转角度
        public float shootFreeTime = 2f;//射击的冷冻时间
        private float shootTimer = 1.5f;//已经射击的时间
        private EnemySight ememySight;//敌人的视野
        private Transform player; 
        public Rigidbody buttle;

    然后在start中初始化一些变量

            ememySight = transform.Find("EnemySight").GetComponent<EnemySight>();
            player = GameObject.FindGameObjectWithTag("Player").transform;

    射击方法和追踪方法都是每帧执行的,所以需要写在update中,
    在update中完善代码

            if (ememySight.playerInSight == true)//如果玩家在敌人的视野内
            {
                Shooting();
                chase = true;
            }
            else if (chase)//如果处于追踪状态
            {
                Chasing();
            }
            else 
            {
                Patrolling();//巡逻状态
            }  

    在下面新建方法Shooting
    射击的过程是首先需要敌人的方向朝向玩家的方向,然后进行射击。

        void Shooting()
        {
            Vector3 lookPos = player.position;//敌人朝向的位置
            lookPos.y = transform.position.y;//因为玩家和敌人有可能y值不一样,所以这里将高度进行统一,防止抬头低头
            Vector3 targetDir = lookPos - transform.position;
            //敌人的朝向转向目标的方向
            transform.rotation = Quaternion.Slerp(transform.rotation, Quaternion.LookRotation(targetDir), Mathf.Min(1f,Time.deltaTime * shootRotSpeed));
            agent.isStopped = true;//让敌人处于停止状态
            if (Vector3.Angle(transform.forward, targetDir) < 6)//如果现在的方向是玩家的方向,这里有个容错范围
            {
                if (shootTimer > shootFreeTime)
                {
                    //实例化出子弹
                    Instantiate(buttle, transform.position, Quaternion.LookRotation(player.position - transform.position));
                    shootTimer = 0f;
                }
                shootTimer += Time.deltaTime;
            }
        }

    敌人追踪

    添加Chasing方法
    追踪的过程是首先根据最后发现玩家的位置进行追踪,如果还是没有找到的话就等待一段时间然后恢复巡逻状态。

        void Chasing()
        {
            agent.isStopped = false;
            Vector3 sightDeltPos = ememySight.playerLastSight - transform.position;//根据最后一次玩家出现的位置进行追踪
            if (sightDeltPos.sqrMagnitude > sqrPlayerDist)
            {
                agent.destination = ememySight.playerLastSight;
            }
            agent.speed = chaseSpeed;
            if (agent.remainingDistance < agent.stoppingDistance)//敌人已经走到玩家最后出现的位置了
            {
                chaseTimer += Time.deltaTime;
                if (chaseTimer > chaseWaitTime)
                {
                    chase = false;
                    chaseTimer = 0f;
                }
            }
            else
                chaseTimer = 0f;
        }
    展开全文
  • 方法通过记录个体接触的时间、地点、接触频率、持续时间等详细信息来构建细粒度的“个体到个体”接触网络。目前常用的接触信息记录手段是调查问卷[6] 、无线通信和无线传感。图 2 示出了两种常用的个体接触追踪...

    12.11 个体接触追踪

    该类方法通过记录个体接触的时间、地点、接触频率、持续时间等详细信息来构建细粒度的“个体到个体”接触网络。目前常用的接触信息记录手段是调查问卷[6] 、无线通信和无线传感。图 2 示出了两种常用的个体接触追踪方法。

    2012 年,Potter 等人采用问卷调查方法研究了某高中 1 074 名学生的接触行为,根据接触时间长度和接触频率等信息构建出局部校园的接触网络,并基于该网络模拟了校园内部的流感爆发过程[7] 。他们研究中发现,教室内部是校园接触的多发场景,课间和午休是校园接触的多发时段。image
    问卷调查方法获得的个体接触信息通常不完整,为了提高个体接触记录的准确性,一些研究者开始寻求移动通讯设备(如手机)或无线传感设备(如可穿戴传感器)的帮助。

    早 在 2006 年, 由 MIT 媒 体 实 验 室 研 究 员Nathan Eagle 和 Alex Pentland 提 出 的 现 实 挖 掘(reality mining)就建议采用可穿戴无线传感设备记录人们的日常活动信息[8-9] 。他们开发了一个实验系统,记录了一些 MIT 学生在教学楼内一段时间的活动轨迹,进而建立了一个描述他们接触关系的小型社会网络[10] 。

    2011 年,Yoneki 研发了首个基于手机终端的接触模式发现软件 FluPhone,该软件可自动检测并记录用户之间的接触行为[11] 。研究者通过该软件收集了剑桥大学校园内 36 名用户的接触信息,构建了用户间不同时段的接触网络,并结合 SEIR模型在该网络上模拟了流感爆发过程。由于 GPS和蓝牙功耗大,导致手机待机时间短,Yoneki 等人将能耗小、使用时间长的可穿戴传感器应用于 FluPhone 软件中,研发了新的接触追踪软件EpiMap [12] 。考虑到流行病爆发的高危地区多分布在经济落后的发展中国家,这些地区的无线通讯设施落后,EpiMap 采用卫星通讯对接触数据进行传输和存储。

    由于可以持续、准确的记录个体的接触事件(如时间、地点、对象、时长),可穿戴无线传感器逐渐成为一种收集“小范围”内高精度接触数据的工具,应用于医院和校园等场景中的接触模式研究。Salathé 等人利用无线传感器收集了美国一所高中788 名学生一天的接触行为,据此构建了一个基于个体的校园接触网络[13] ,进而发现校园接触网络具有高密度连接和小世界结构的特征[14] 。Isella 等人使用射频识别设备采集了美国一所儿童医院 119人(包括医护人员、重症儿童和护理人员)之间的16 000 次接触,建立了医院场景的接触结构[15] 。类似的,Stehlé 等人使用无线射频识别设备采集了一所法国小学内学生的接触数据[16] 。

    无线射频追踪器的收发距离有限,只能在某一特定区域正常工作。2016 年,IBM 非洲实验室的研究员 Kurien 和 Shingirirai 发明了一种无线电标签,解决了追踪器收发距离短的问题,并将该技术用于结核病追踪[1] (见图 3)。每块标签包含有一个小型传感器、存储设备和电池。被个体携带的无线电标签可以互相通讯,当两个标签互联时,个体接触行为就被记录下来。无线电标签收集的接触数据集中呈现在一个三维可视化系统中,利用该系统提供的智能数据分析方法,医疗人员能够实时查看结核病患者的时空分布,追踪结核病毒的传播路径,发现高风险易感人群。由于结核病疫苗费用很高,这些接触数据还可帮助医疗人员确定疫苗接种个体的优先级。image
    虽然使用分发 / 收集调查问卷、移动通讯设备或无线传感设备可以收集到非常细致的个体接触信息,但由于过于昂贵的成本,这类方法大都局限在小规模人口的实验中,还没有推广到大范围、大规模个体接触行为的追踪与分析。采用无线可穿戴设备追踪个体接触的另一个问题是隐私问题。这些用作医疗数据收集的追踪器除了记录接触行为,也很容易追踪和记录人的移动轨迹,而这些通常都会被认为是侵犯隐私的做法。另一个敏感的问题在于,佩戴追踪器等于向别人宣告自己是某种传染病的患者。例如,在非洲国家,肺结核患者会被打上社会偏见的烙印。

    展开全文
  • 在之前c#自己封装一个轻量级ORM框架FastORM一文中已经初步完成了对数据库查询,实体映射,泛型方法的封装,但是对于更新字段使用的还是全字段更新,也没有日志追踪功能,在本文中,将会详细叙述完善这两个功能的...

    在之前c#自己封装一个轻量级ORM框架FastORM一文中已经初步完成了对数据库查询,实体类映射,泛型方法的封装,但是对于更新字段使用的还是全字段更新,也没有日志追踪功能,在本文中,将会详细叙述完善这两个功能的过程。

    更新操作字段的智能识别:

    之前的FastORM初始版本的强类型更新操作,是对对象的全字段更新,如果其中含有大文本存储,将会增加数据库服务器的压力,所以决定对更新操作进行优化。首先的思路是对实体对象的Set操作进行记录,例如

        public string LoginID
        {
           get;
           set
           {
               base.SetState(value);
           }
        }

    但是这种操作会增加实体类的繁琐程度,所以决定在实体类的基类中进行属性Set方法的AOP拦截,使用到c#自带的ProxyAttribute和RealProxy两个类,先来看下这两个类有什么作用

    ProxyAttribute这个类用来截获对象的代理,我们只要能够替换代理,就能够在对象的初始化,方法调用的过程中加入自定义的操作,重写MarshalByRefObject方法,进行代替替换

            public override MarshalByRefObject CreateInstance(Type serverType)
            {
                SetMethodAopProxy realProxy = new SetMethodAopProxy(serverType);
                return realProxy.GetTransparentProxy() as MarshalByRefObject;
            }

    那我们如何生成自己的代理呢,接下来就要使用到RealProxy这个抽象类

    乍一看微软的注解可能看不明白意思,我们一点点来分析,首先理解一下什么是代理,打个比方,个对象A的有一个方法C,但是不直接调用,而是通过一个类B,将A对象作为一个参数在B的构造函数中传入,并在B的同名方法C中调用对象A的方法C,并在方法前后加入自己的操作,对于对象A,只关心方法C的操作,对于对象B只关心对象A方法C前后的操作,类似于系统中AOP的日志记录功能

    透明代理和代理的作用其实是一样的,但是是作为代理内部的转发,举个生活中的例子,我们使用的电脑是客户端,路由器就是代理,使用的ssr进行科学上网就是透明代理,你感觉不到ssr的存在,只觉得自己通过路由器就能访问Google,具体请看下面的代码

        class SetMethodAop : ProxyAttribute
        {
            public override MarshalByRefObject CreateInstance(Type serverType)
            {
                SetMethodAopProxy realProxy = new SetMethodAopProxy(serverType);
                return realProxy.GetTransparentProxy() as MarshalByRefObject;
            }
        }

    其中SetMethodAop就是真实代理,但是是表现为Attribue的无入侵方式,SetMethodAopProxy就是透明代理,将代理转发到RealProxy的SetMethodAopProxy的方法

     public class SetMethodAopProxy : RealProxy
        {
            public SetMethodAopProxy(Type serverType)
                : base(serverType)
            {
            }
    
            public override IMessage Invoke(IMessage msg)
            {
               
    
            }
    
        }

    SetMethodAop这个类继承自RealProxy这个抽象类,复写的IMessage方法就是代理过程的处理,接下来就是拦截Set方法的具体实现

                if (msg is IConstructionCallMessage) // 如果是构造函数,按原来的方式返回即可。
                {
                    IConstructionCallMessage constructCallMsg = msg as IConstructionCallMessage;
                    IConstructionReturnMessage constructionReturnMessage = this.InitializeServerObject((IConstructionCallMessage)msg);
                    RealProxy.SetStubData(this, constructionReturnMessage.ReturnValue);
                    return constructionReturnMessage;
                }
                else if (msg is IMethodCallMessage) //如果是方法调用(属性也是方法调用的一种)
                {
    
                    IMethodCallMessage callMsg = msg as IMethodCallMessage;
                    object[] args = callMsg.Args;
                    IMessage message;
                    try
                    {
                        //如果是set方法,且不是设置ModelState的方法,且ModelState为Modified时,记录更新字段
                        if (callMsg.MethodName.StartsWith("set_") && args.Length == 1 && !callMsg.MethodName.Contains("ModelState"))
                        {
                            object obj = GetUnwrappedServer();
                            Type type = obj.GetType();
                            PropertyInfo ModelState = type.GetProperty("ModelState");
                            if ((ModelStateEnum)ModelState.GetValue(obj)==ModelStateEnum.Modified)
                            {
                                string fieldname = callMsg.MethodName.Split(new char[] { '_' }, StringSplitOptions.RemoveEmptyEntries)[1];
                                foreach (FieldInfo field in type.GetFields())
                                {
                                    if (field.Name == "ModifyFieldList")
                                    {
                                        List<string> ModifyFieldList = field.GetValue(obj) as List<string>;
                                        if (!ModifyFieldList.Contains(fieldname))
                                        {
                                            ModifyFieldList.Add(fieldname);
                                            field.SetValue(obj, ModifyFieldList);
                                        }
                                        break;
                                    }
    
                                }
                            }
                            
                        }
                        object o = callMsg.MethodBase.Invoke(GetUnwrappedServer(), args);
                        message = new ReturnMessage(o, args, args.Length, callMsg.LogicalCallContext, callMsg);
                    }
                    catch (Exception e)
                    {
                        message = new ReturnMessage(e, callMsg);
                    }
                    return message;
                }
                return msg;

    判断MethodInfo的以set_开头并且不为设置基类状态属性ModelState的方法,将修改的字段存储内部的ModifyFieldList的List中,需要注意的是Model的基类需要继承ContextBoundObject对象

    ORM的SQL语句追踪:

    对于SQL语句的追踪就用到了c#的AOP拦截,原来是打算也使用ProxyAttribute进行拦截,但是因为基类操作对象中存在类似于public List<T> QueryCommand<T>()的泛型方法,会导致TypeLoadExcetion,最后发现是由于微软的ContextBoundObject限制,继承类中不能存在泛型方法,只能找别的方法,这里是使用的DynamicProxy动态代理。

    先总结一下动态代理的几种实现方式

    1.静态代理:使用代理类进行代码插入,业务复杂后代理类会繁杂增多

    2.动态代理:可以使用三方插件,或者用微软提供代理库编写,FastORM就是使用的这种方式,但是对性能有一定的损失

    3.IL编织,三方插件PostSharp就是用此种方式,性能与原生调用基本没有差别,通过对编译后的文件进行操作,在运行前插入AOP代码,缺点是PostSharp收费,并且调试比较困难

    接下来就介绍如何写一个动态代理类,首先看代码

    class DynamicProxy<T> : RealProxy
        {
            private readonly T _decorated;
            private Predicate<MethodInfo> _filter;
            public event EventHandler<HandleArg> BeforeExecute;
            public event EventHandler<HandleArg> AfterExecute;
            public event EventHandler<HandleArg> ErrorExecuting;
            public DynamicProxy(T decorated)
                : base(typeof(T))
            {
                _decorated = decorated;
                Filter = m => true;
            }
            public Predicate<MethodInfo> Filter
            {
                get { return _filter; }
                set
                {
                    if (value == null)
                        _filter = m => true;
                    else
                        _filter = value;
                }
            }
            private void OnBeforeExecute(HandleArg args)
            {
                if (BeforeExecute != null)
                {
                    var methodInfo = args.MethodCall.MethodBase as MethodInfo;
                    if (_filter(methodInfo))
                    {
                        BeforeExecute(this, args);
                       
                    }
                       
                }
            }
            private void OnAfterExecute(HandleArg args)
            {
                if (AfterExecute != null)
                {
                    var methodInfo = args.MethodCall.MethodBase as MethodInfo;
                    if (_filter(methodInfo))
                    {
                        AfterExecute(this, args);
    
                    }
                        
                }
            }
            private void OnErrorExecuting(HandleArg args)
            {
                if (ErrorExecuting != null)
                {
                    var methodInfo = args.MethodCall.MethodBase as MethodInfo;
                    if (_filter(methodInfo))
                    {
                        AfterExecute(this, args);
    
                    }
                       
                }
            }
            public override IMessage Invoke(IMessage msg)
            {
                var methodCall = msg as IMethodCallMessage;
                var methodInfo = methodCall.MethodBase as MethodInfo;
                HandleArg args = new HandleArg();
                args.Obj = _decorated;
                args.MethodCall = methodCall;
                OnBeforeExecute(args);
                try
                {
                    var result = methodInfo.Invoke(_decorated, methodCall.InArgs);
                    OnAfterExecute(args);
                    return new ReturnMessage(
                      result, null, 0, methodCall.LogicalCallContext, methodCall);
                }
                catch (Exception e)
                {
                    OnErrorExecuting(args);
                    return new ReturnMessage(e, methodCall);
                }
            }

    同样也是继承与RealProxy方法,在Invoke方法中进行拦截写入代码,但是这里使用了委托事件,在调用的过程中调用委托,把具体的实现交由创建生成被代理类的工厂类,不在动态代理类中进行具体AOP的操作,增加了动态代理的高复用性与灵活性,同时增加了MethodInfo的过滤器,对拦截方法进行过滤,接下来看下被代理类的生成代码

        public class CommandFactory
        {
    
            public static Command Create(bool IsTrace)
            {
                var repository = new Command();
                if (IsTrace)
                {
                    repository.IsTrace = IsTrace;
                }
                var dynamicProxy = new DynamicProxy<Command>(repository);
                dynamicProxy.BeforeExecute += BeforeExecute;
                dynamicProxy.AfterExecute += AfterExecute;
                dynamicProxy.ErrorExecuting += ErrorExecuting;
                //只监听TraceMethod方法
                dynamicProxy.Filter = m => m.GetCustomAttributes(typeof(TraceMethod),false).Count()>0;
                return dynamicProxy.GetTransparentProxy() as Command;
            }
    
            public static void BeforeExecute(object sender, HandleArg e)
            {
    
            }
            public static void AfterExecute(object sender, HandleArg e)
            {
                object obj = e.Obj;
                Type type = obj.GetType();
                bool IsTrace = Convert.ToBoolean(type.GetProperty("IsTrace").GetValue(obj));
                if (IsTrace)
                {
                    //调用对象的Trace方法
                    MethodInfo method = type.GetMethod("Trace", new Type[] { });
                    object[] parameters = null;
                    method.Invoke(obj, parameters);
                }
              
            }
            public static void ErrorExecuting(object sender, HandleArg e)
            {
    
            }

    我这里仅使用了AfterExecute委托,调用被代理类的Trace方法追踪SQL语句,这里为什么不直接加入对应的日志记录操作呢,因为获取内部对象信息也需要使用多次反射,而调用方法只需要一次,提高程序的性能,而且可以将Trace方法写入接口作为标准,更利于使用动态代理对象的集中管理,需要注意的是,被代理类需要继承MarshalByRefObject类。

    项目地址:https://gitee.com/grassprogramming/FastORM

    参考资料:https://msdn.microsoft.com/zh-cn/library/dn574804.aspx

    展开全文
  • 智能指针之辅助

    2014-08-31 22:48:50
    中包含指针的,在进行拷贝构造或者赋值操作时要尤其小心,但是往往很难避开悬挂指针的问题。 智能指针的实现是通过引用计数来完成的。将一个指针对象和引用计数关联起来,使用引用计数来追踪对象的使用。...
  • 12.12 群体接触追踪 为了克服细粒度个体接触数据难以获取的困难,近年来,能够刻画人口异构特征,并能建模流行病传播动力学的复合群体模型(见图 4)正日益受到关注。这模型不仅具备模拟传播过程的能力,还能刻画...
  • C++ Primer----智能指针 2

    千次阅读 2014-04-14 21:30:30
    指针带给了 C++巨大的灵活性,然而同样也带来无数的问题,悬挂指针,内存泄漏等。 int *pInt = new int(1); // Do not forget ...一种智能指针的实现方法是,通过一个计数,追踪当前指向同一块地址的指
  • 在现在的办理形式下,财物变动信息在传递进程中人为因素形成的信息失真和滞后引起帐实无法同步一致,网络部分无法及时进行设备优化分配,致使很多高价值网络财物搁置糟蹋,严重影响电信财物的功率和财政报告的真实...
  • 控制终端: 由静脉/指纹活体高端生物识别技术作为身份认证,操控箱体内工具的取、还,追踪并记录下工具流程的信息。可以连接485/互联网进行远程BS/CS实时管理。 4.智能箱体: 四项实用新型专利设计,加厚钢板外壳,...
  • 公司的物联网智能终端、LTE模块产品及无线数据解决方案已经在移动支付、车联网、安防、工业路由、消费电子、智能电力、智能抄表、智能终端、物品追踪等领域形成大规模应用。精密组件业务已进入国内顶尖消费品牌的...
  • 腾讯数码讯(言言)尽管苹果、Fitbit和小米在智能手表和健身追踪可穿戴设备上已经取得了瞩目的成绩,但是智能珠宝的产品依然还是吸引了很多追随者,时尚的男女们都愿意通过这种更好的方式,来体验智能特性。...
  • 公司的物联网智能终端、LTE模块产品及无线数据解决方案已经在移动支付、车联网、安防、工业路由、消费电子、智能电力、智能抄表、智能终端、物品追踪等领域形成大规模应用。精密组件业务已进入国内顶尖消费品牌的...
  • 国际数据公司(IDC)与百度AI产业研究中心(BACC)联合发布了《百度大脑领导力白皮书》,白皮书中追踪了16个行业的66个应用场景,并将人工智能在企业的应用划分成产品服务、生产模式、运营模式以及决策端4大。...
  • 公司的物联网智能终端、LTE模块产品及无线数据解决方案已经在移动支付、车联网、安防、工业路由、消费电子、智能电力、智能抄表、智能终端、物品追踪等领域形成大规模应用。精密组件业务已进入国内顶尖消费品牌的...
  • 引言  许多太阳能电池板供电型应用只需功率脉冲便...本文将为您介绍一种简单且高成本效益的最大功率点追踪 (MPPT) 解决方案,以供这脉冲负载系统使用。  太阳能电池板特性  在最大功率点工作时,太阳能电池板
  • 智能监控技术智能监控技术就是使用计算机图像视觉分析技术,通过将场景中背景和目标分离进而分析并追踪在摄像机场景内目标。用户可以根据的分析模块,通过在不同摄像机的场景中预设不同的非法规则,一旦目标在场景中...
  • UE4中的智能指针

    2020-10-27 14:26:58
    智能指针库:减轻内存分配与追踪负担 ,C++11中智能指针的定义实现 共享指针TSharedPtr 共享引用 TSharedRef(不可为空) 弱指针 TWeakPtr 助手与函数 助手与函数 MakeShareable()-用于从C ++指针初始化...
  • 公司的物联网智能终端、LTE模块产品及无线数据解决方案已经在移动支付、车联网、安防、工业路由、消费电子、智能电力、智能抄表、智能终端、物品追踪等领域形成大规模应用。精密组件业务已进入国内顶尖消费品牌的...
  • 国外媒体撰文指出,可穿戴运动追踪设备的去手机化正在到来,智能手机不会一直都是该设备的中心。不过该运动还需要新的网络、新的元件和新的思维。
  • 智能化工单正式启动

    2019-08-22 18:03:43
    对外开放是可用以举报,提议,售后服务,安裝检修的系统软件,是这种用手机软件全自动派发传单检修的智能控制系统,像嚓嚓在线客服的智能化工单系统就归属于这类别。 嚓嚓在线客服智能化工单系统是由稳网互联全...
  • 目前市面上常见的动作捕捉分为两:惯性动作捕捉与光学动作捕捉,光学动作捕捉又分为红外、激光、可见光与机器视觉等。先来了解一下惯性动捕,在具体提到惯性动作捕捉之前,大家比较熟悉的惯性技术应该更多在于我们...
  • 公司的物联网智能终端、LTE模块产品及无线数据解决方案已经在移动支付、车联网、安防、工业路由、消费电子、智能电力、智能抄表、智能终端、物品追踪等领域形成大规模应用。精密组件业务已进入国内顶尖消费品牌的...
  • 公司的物联网智能终端、LTE模块产品及无线数据解决方案已经在移动支付、车联网、安防、工业路由、消费电子、智能电力、智能抄表、智能终端、物品追踪等领域形成大规模应用。精密组件业务已进入国内顶尖消费品牌的...
  • 公司的物联网智能终端、LTE模块产品及无线数据解决方案已经在移动支付、车联网、安防、工业路由、消费电子、智能电力、智能抄表、智能终端、物品追踪等领域形成大规模应用。精密组件业务已进入国内顶尖消费品牌的...
  • “人工智能取代人类工作”之的新闻大标题常常让我们惊出一身冷汗。不过,至少现在你不用过于担心,因为它还处在发展水平最低的阶段。无论是击败人类顶级围棋手的AlphaGo,亦或是打败DOTA顶级职业玩家的OpenAI团队...
  • 公司的物联网智能终端、LTE模块产品及无线数据解决方案已经在移动支付、车联网、安防、工业路由、消费电子、智能电力、智能抄表、智能终端、物品追踪等领域形成大规模应用。精密组件业务已进入国内顶尖消费品牌的...
  • 追踪学术界、产业界、开源软件和公共兴趣范畴的18个分立的视角评估人工智能活跃度,盘点计算机视觉、自然语言理解等技术发展现状(机器人程度),从专家视角解读人工智能创业和投资的急剧增加,探讨相关领域的深入...
  • 公司的物联网智能终端、LTE模块产品及无线数据解决方案已经在移动支付、车联网、安防、工业路由、消费电子、智能电力、智能抄表、智能终端、物品追踪等领域形成大规模应用。精密组件业务已进入国内顶尖消费品牌的...
  • 公司的物联网智能终端、LTE模块产品及无线数据解决方案已经在移动支付、车联网、安防、工业路由、消费电子、智能电力、智能抄表、智能终端、物品追踪等领域形成大规模应用。精密组件业务已进入国内顶尖消费品牌的...

空空如也

空空如也

1 2 3 4 5 ... 8
收藏数 147
精华内容 58
关键字:

智能追踪类