ET介绍——CSharp协程

什么是协程

说到协程,我们先了解什么是异步,异步简单说来就是,我要发起一个调用,但是这个被调用方(可能是其它线程,也可能是IO)出结果需要一段时间,我不想让这个调用阻塞住调用方的整个线程,因此传给被调用方一个回调函数,被调用方运行完成后回调这个回调函数就能通知调用方继续往下执行。举个例子:
下面的代码,主线程一直循环,每循环一次sleep 1毫秒,计数加一,每10000次打印一次。

private static void Main()
        {
            int loopCount = 0;
            while (true)
            {
                int temp = watcherValue;
                
                Thread.Sleep(1);
                
                ++loopCount;
                if (loopCount % 10000 == 0)
                {
                    Console.WriteLine($"loop count: {loopCount}");
                }
            }
        }

 

这时我需要加个功能,在程序一开始,我希望在5秒钟之后打印出loopCount的值。看到5秒后我们可以想到Sleep方法,它会阻塞线程一定时间然后继续执行。我们显然不能在主线程中Sleep,因为会破坏掉每10000次计数打印一次的逻辑。

// example2_1
    class Program
    {
        private static int loopCount = 0;

        private static void Main()
        {
            OneThreadSynchronizationContext _ = OneThreadSynchronizationContext.Instance;
            
            WaitTimeAsync(5000, WaitTimeFinishCallback);
            
            while (true)
            {
                OneThreadSynchronizationContext.Instance.Update();
                
                Thread.Sleep(1);
                
                ++loopCount;
                if (loopCount % 10000 == 0)
                {
                    Console.WriteLine($"loop count: {loopCount}");
                }
            }
        }

        private static void WaitTimeAsync(int waitTime, Action action)
        {
            Thread thread = new Thread(()=>WaitTime(waitTime, action));
            thread.Start();
        }
        
        private static void WaitTimeFinishCallback()
        {
            Console.WriteLine($"WaitTimeAsync finsih loopCount的值是: {loopCount}");
        }

        /// <summary>
        /// 在另外的线程等待
        /// </summary>
        private static void WaitTime(int waitTime, Action action)
        {
            Thread.Sleep(waitTime);
            
            // 将action扔回主线程执行
            OneThreadSynchronizationContext.Instance.Post((o)=>action(), null);
        }
    }

 

我们在这里设计了一个WaitTimeAsync方法,WaitTimeAsync其实就是一个典型的异步方法,它从主线程发起调用,传入了一个WaitTimeFinishCallback回调方法做参数,开启了一个线程,线程Sleep一定时间后,将传过来的回调扔回到主线程执行。OneThreadSynchronizationContext是一个跨线程队列,任何线程可以往里面扔委托,OneThreadSynchronizationContext的Update方法在主线程中调用,会将这些委托取出来放到主线程执行。为什么回调方法需要扔回到主线程执行呢?因为回调方法中读取了loopCount,loopCount在主线程中也有读写,所以要么加锁,要么永远保证只在主线程中读写。加锁是个不好的做法,代码中到处是锁会导致阅读跟维护困难,很容易产生多线程bug。这种将逻辑打包成委托然后扔回另外一个线程是多线程开发中常用的技巧。

我们可能又有个新需求,WaitTimeFinishCallback执行完成之后,再想等3秒,再打印一下loopCount。

private static void WaitTimeAsync(int waitTime, Action action)
        {
            Thread thread = new Thread(()=>WaitTime(waitTime, action));
            thread.Start();
        }
        private static void WaitTimeFinishCallback()
        {
            Console.WriteLine($"WaitTimeAsync finsih loopCount的值是: {loopCount}");
            WaitTimeAsync(3000, WaitTimeFinishCallback2);
        }
        
        private static void WaitTimeFinishCallback2()
        {
            Console.WriteLine($"WaitTimeAsync finsih loopCount的值是: {loopCount}");
        }

 

我们这时还可能改需求,需要在程序启动5秒后,接下来4秒,再接下来3秒,打印loopCount,也就是上面的逻辑中间再插入一个3秒等待。

private static void WaitTimeAsync(int waitTime, Action action)
        {
            Thread thread = new Thread(()=>WaitTime(waitTime, action));
            thread.Start();
        }
        
        private static void WaitTimeFinishCallback()
        {
            Console.WriteLine($"WaitTimeAsync finsih loopCount的值是: {loopCount}");
            WaitTimeAsync(4000, WaitTimeFinishCallback3);
        }
        
        private static void WaitTimeFinishCallback3()
        {
            Console.WriteLine($"WaitTimeAsync finsih loopCount的值是: {loopCount}");
            WaitTimeAsync(3000, WaitTimeFinishCallback2);
        }
        
        private static void WaitTimeFinishCallback2()
        {
            Console.WriteLine($"WaitTimeAsync finsih loopCount的值是: {loopCount}");
        }

 

这样中间插入一段代码,显得非常麻烦。这里可以回答什么是协程了,其实这一串串回调就是协程。

ET开源地址地址:egametang/ET: Unity3D Client And C# Server Framework (github.com)   qq群:474643097

本文转载于网络 如有侵权请联系删除

相关文章

  • 进阶|15分钟轻松理解HTTPS

    前端爱好者的知识盛宴嗨这里是IMWEB一个想为更多的前端人享知识 助发展觅福利有情怀有情调的公众号欢迎关注转发让更多的前端技友一起学习发展~导语它很深奥吗?你肯定常常见过它,使用它,甚至离不开它...它很浅显吗?你可能觉得看透它,理解它,甚至懂它...让我们用15分钟,不那么学术地将它的深挖到底~举   栗  子什么?如何证明我是我?本文要上升到这样的哲学高度了吗?吓得作者笔都掉了,不,是键盘按键都飞出来了… HTTPS的身份认证机制还真的是一个“如何证明我是我”的问题,并且巧妙地使用了“零知识证明”。先来看个故事吧!我知道某带密码门锁房间的密码,如何证明我有这个密码呢?下面有两种方式: ①我把密码告诉你,你用密码打开该房间的锁。②我们都知道房间内有某一物体,我用密码打开房间的门,然后把物体拿出来给你看。方式①的结果是密码泄漏了,如果换作二战被俘的情报员或者被四十大盗劫持的阿里巴巴身上,他们的结局一定是被无情杀害了。方式②是零知识证明。它指的是证明者能够在不向验证者提供任何有用的信息的情况下,使验证者相信某个论断是正确的。那下面我们来挖一挖HTTPS如何借鉴这种思想进行身份认证的。不

  • 源码分析-Netty:多线程在 Netty 中的应用

    系列文章:源码分析-Netty:开篇一Netty线程模型需要注意的是,Netty的线程模型并非固定不变,而是取决于用户的启动参数配置。通过启动参数的设置,Netty可以支持Reactor单线程模型和多线程模型。二Java内存模型与多线程2.1Java内存模型(JMM)Java的内存模型JMM,我们在并发编程艺术相关文章中有过详细的阐述。感兴趣的可以回顾文章:【并发编程的艺术】Java内存模型总结。简单来说,JVM规范定义了Java内存模型,来屏蔽各种操作系统、虚拟机实现厂商和硬件的内存访问差异,从而确保Java程序在所有操作系统和平台上能够实现相同的效果。2.2多线程并发,是高性能编程中一个重要概念。也可以通过单进程-单线程模型,在机器上启动多个进程来实现多任务并行执行。也可以像在Java中,通过单进程-多线程模型来执行多任务并发处理。线程,作为调度执行单元,比进程更加轻量。可以把进程的资源分配和调度执行分开,一个进程下的多个线程可以共享内存、I/O等操作系统资源,同时能被操作系统发起的内核线程或进程执行各线程可以独立启动、运行、停止,实现任务的拆分解耦。线程的主要实现方式,在主流操作

  • 交易系统架构演进之路(一):1.0版

    前言近几年,我在资产证券类交易系统领域做得比较多,从2016年开始,在贵金属交易领域深耕了两年,负责的交易平台用户量曾达到几百万,日活也有几十万,日流水更是千万级别。2018年之后,在数字资产交易行业又沉淀了两年,虽然用户量级没达到之前在贵金属交易平台的级别,但因为交易标的明显比在贵金属时多得多,所以整体的并发量和交易量却大得多。基于我这几年的经验总结,我将以数字资产交易平台为案例,聊聊从0到1再到N的交易系统的架构应该如何不断演进。第一篇文章先从起步阶段开始。需求分析任何架构的演进都是由场景驱动的,离开场景谈架构就是耍流氓。因此,做架构设计之前,我们要先了解当下的场景。场景就是需求,一般可以将需求分为三类:商业需求、功能需求和质量需求。商业需求是最高层次的需求,它关注从客户群、企业现状、未来发展、预算、立项、开发、运营、维护在内的整个软件生命周期涉及的商业因素,包括了商业层面的目标、期望和限制等。商业需求一般对架构的影响比较大,对架构产生限制的商业因素也比较多,比较常见的包括:上市时间、成本预算、人力现状、目标市场、阶段性计划、国际化等等。功能需求描述的就是系统应该提供的服务,包括为

  • Dubbo——服务目录

    引言前面几篇文章分析了Dubbo的核心工作原理,本篇将对之前涉及到但却未细讲的服务目录进行深入分析,在开始之前先结合前面的文章思考下什么是服务目录?它的作用是什么?正文概念及作用清楚Dubbo的调用过程就知道Dubbo在客户端和服务端都会为服务生成一个Invoker执行体,这个Invoker包含了所有的配置信息,也相当于是一个代理对象,所以这也就引发出几个问题:怎么管理Invoker?不可能让用户自己去管理,也不可能客户端每次调用服务时都新创建Invoker。当服务存在集群时,选择使用哪一个Invoker?怎么选择?服务列表变化时,Invoker列表怎么更新?针对以上问题,Dubbo引入了服务目录的概念,简单的说就是Invoker的集合,由框架自身统一管理Invoker列表,并且提供订阅服务功能,使得服务变更时,会自动更新Invoker列表;同时当存在集群时,可以使得外部以统一的方法使用Invoker,即用户不用关心怎么选择使用哪一个Invoker(在之前的源码分析中我们看到过cluster.join就是实现该功能的API,将多个Invoker合成一个Invoker)。继承结构了解了基

  • 分析粪便微生物移植后患者高通量单分子实时测序数据的工作流程

    有许多基于测序的方法来了解复杂宏基因组,从全样本鸟枪法测序到靶向扩增。虽然靶向方法在低测序深度提供有价值的数据,但它们受引物设计和PCR限制。全样本鸟枪法通常使用短读长测序,这导致数据处理困难。例如,长度小于500bp的读数很少覆盖完整的感兴趣的基因或区域,所以将需要组装。这不仅引入了来自不同社区成员的序列不正确地拼接的可能性,还需要高覆盖深度。因此,罕见的社区成员可能不会在结果集合中被表示。、循环共识,单分子实时(SMRT)测序读长在1-3kb范围内,精度可达99%以上,可以使用上一代PacBioRSII产生,或者在更高的通量下,使用新的Sequel系统。尽管与短读取测序方法相比,吞吐量较低,但读长是社区的真实随机抽样,因为SMRT测序已被证明具有非常低的序列偏好。单分子读数>1kb,>99%的共有准确度,可以合理地利用高比例的reads包括可用于分析的基因或基因片段,而无需重新组装。在这里,我们介绍了在进行粪便微生物群移植(FMT)之前和之后,为了治疗慢性艰难梭菌感染的个体微生物群的循环共识测序的结果。我们显示即使具有相对较低的测序深度,长读长,无装配,随机抽样也可以让

  • Python练手例子(11)

    61、打印出杨辉三角形。#python3.7 fromsysimportstdout if__name__=='__main__': a=[] foriinrange(10): a.append([]) forjinrange(10): a[i].append(0) foriinrange(10): a[i][0]=1 a[i][i]=1 foriinrange(2,10): forjinrange(1,i): a[i][j]=a[i-1][j-1]+a[i-1][j] foriinrange(10): forjinrange(i+1): stdout.write(str(a[i][j])) stdout.write('') print()复制62、查找字符串。#python3.7 sStr1='language' sStr2='age' print(sStr1.find(sStr2)) 结果: 5复制63、使用Tkinter画椭圆。#python3.7 fromtkinterimport* if_

  • 设计模式(四)——代理模式

    代理模式定义:为其他对象提供一种代理以控制对这个对象的访问上图中,Subject是一个抽象类或者接口,RealSubject是实现方法类,具体的业务执行,Proxy则是RealSubject的代理,直接和client接触的。代理模式可以在不修改被代理对象的基础上,通过扩展代理类,进行一些功能的附加与增强。值得注意的是,代理类和被代理类应该共同实现一个接口,或者是共同继承某个类。代理模式优点职责清晰高扩展,只要实现了接口,都可以用代理。智能化,动态代理。分类代码:GitHub1、静态代理以租房为例,我们一般用租房软件、找中介或者找房东。这里的中介就是代理者。首先定义一个提供了租房方法的接口。publicinterfaceIRentHose{voidrentHose();}复制定义租房的实现类publicclassRentHoseimplementsIRentHose{@OverridepublicvoidrentHose(){System.out.println("租了一间房子。。。");}}复制我要租房,房源都在中介手中,所以找中介publicclassInterm

  • 2018-10-16 svn迁移到Git svn上r80000个哭

    这活不应该是Linux管理员的干的吗?什么时候轮到程序员了,操蛋,想清楚自己是干啥的,是为了工作而工作还是为了目标而工作做完一次发现原来好简单哦,但这话你应该跟别人说嘛?没心情整理文章,下面是做这个事情参考的部分资料,读完加上动手能力应该可以搞定这件事了,这是我踩坑的?最开始follow这个doc做的 https://www.zybuluo.com/Jazka/note/173956 可是好多坑后来又参考了 https://cloud.tencent.com/developer/section/1138668参考资料比较靠前的几个比较好用由于Giglab上创建项目的时候自动创建了readme.md所以push不上去 https://github.com/LeachZhou/blog/issues/11参考资料: SVN切换到Git方法及坑点 https://oliverqueen.cn/2018/08/23/ChangeSvnToGit/ 如何从SVN迁移源码到Git仓库 https://blog.waterstrong.me/svn-to-git-migration/ svn迁移到g

  • 聊聊iOS中的 MVC、MVP、MVVM以及 VIPER等代码组织方式

    前言本文下面所谈的所谓架构二字,核心即是对于客户端的代码组织/职责划分。现在我们面对架构设计模式的时候有了很多选择: -MVC -MVP -MVVM -VIPER 首先前三种模式都是把所有的实体归类到了下面三种分类中的一种: -Models(模型)数据层,或者负责处理数据的数据接口层。 -Views(视图)-展示层(GUI)。对于iOS理论上来来说所有以UI开头的类基本都属于这层。 -Controller/Presenter/ViewModel(控制器/展示器/视图模型) 它是Model和View之间的胶水或者说是中间人。 一般来说,当用户对View有操作时它负责去修改相应Model;当Model的值发生变化时它负责去更新对应View。复制一、MVC“架构”(1)MVC-它原来的样子 经典MVC模式在提出时,大致是上图这样的。更贴近现时代得说,在这种架构下,View是无状态的, 在Model变化的时候它只是简单的被Controller重绘, 尽管这种架构可以在应用里面实现,但是由于MVC的三种实体被紧密耦合着,每一种实体都和其他两种有着联系, 所以即便是实现了也没有什么意义。复制(

  • 零基础使用Django2.0.1打造在线教育网站(二):开发环境配置

    关于博主努力与运动兼备~有任何问题可以加我好友或者关注微信公众号,欢迎交流,我们一起进步!微信公众号:啃饼思录:复制QQ:2810706745(啃饼小白)复制写在前面俗话说得好,工欲善其事,必先利其器!开发环境的搭建是你进行程序开发的基础,也是关键所在。网站开发过程中主要用到的软件有Pycharm,Mysql,Navicat,Python下面结合我的版本给大家一一演示如何安装。软件介绍我的软件版本Pycharm我这里没有升级,采用的是JetBrainsPyCharm2017.3.4x64 Mysql,这里我采用了比较好用的mysql-5.7.21-winx64 Navicat,这里采用了NavicatPremium,当然其他如NavicatforMysql也可以 Python,写文章的时候Python3.7.0刚刚发布,鉴于其他插件还没有进行适配,我采用Python3.6.4这个版本进行开发。Pycharm的安装1、软件位置PyCharm2017/64位下载地址:链接:https://pan.baidu.com/s/1nwhmx2D密码:pc612、右击软件压缩包选择解压到pychar

  • .NET应用架构设计—面向查询服务的参数化查询设计(分解业务点,单独配置各自的数据查询契约)

    阅读目录:1.背景介绍2.对业务功能点进行逻辑划分(如:A、B、C分别三个业务点)2.1.配置映射关系,对业务点配置查询契约(构造VS插件方便生成查询契约)2.2.将配置好的映射策略文件放在调用端,与服务不耦合3.Dynamic、Dom动态构造服务端对象(Dynamic、DOM实现动态DOM)1.背景介绍现在越来越多的公司都在尝试SOA架构的实践,本人最近也在尝试学习这方面的技术,但是在实践过程中遇到一个问题,我想这个问题也是我们普遍实践者都应该会遇到的问题,问题描述如下:我们有一个SOA商品(Item)查询接口,这个接口很通用,主要用来支撑日常很多其他系统的大量关于Item的查询,尤其是在高峰期间该服务的压力是很大的;我们站在SOA的角度看这个接口,这个通用的接口解决了众多的查询业务,确实不错,但是我们切换一下角度,站在每一个调用接口的访问端看似乎并不是很满意或者说牺牲了部分性能上的代价,因为我们无法干净利落的只获取当前这个业务点需要的数据项;这个Item服务接口所返回的数据项必须同时满足所有调用它的业务点,哪怕这次调用我只需要用到Item的三分之一的数据字段都不行,每次都会把不需要

  • 算法-获取链表中倒数第k个结点

    题目: 输入一个链表,输出该链表中的倒数第k个结点。比如链表中的值为1,2,3,4,5,6。倒数第三个结点为值为4的结点。链表定义如下:structListNode { intvalue; ListNode*next; };复制解题思路: 这个问题相对来说还是挺好理解的,要找到倒数第k个结点,最直接的思路肯定是倒着数k个结点不就好了,但是问题是链表不能从尾结点开始遍历,只能从头结点开始。 那么倒数第k个的问题基于必须要转化成正数第n-k+1个,其中n是整个链表的长度,那么问题就可以这样解决: (1)先遍历一遍链表,得到链表的长度n; (2)再从头遍历链表,遍历到n-k+1个就是要找到的倒数第k个结点。 但是这种方法必须要遍历两次,那么有没有遍历一次就得到正确结果的方法呢? 可以通过定义两个指针,第一个指针p1先走k-1步后第二个指针p2再开始走,到k步时两个指针同步走,那么当p1到底链表的结尾时,p2正好走到了第k个结点。 此时这种方法牺牲了空间复杂度(两个指针),换来了时间复杂度的降低,这也是设计算法时比较常用的方式—“用空间换时间”。代码实现:ListNode*FindKthTo

  • 腾讯云容器服务查询边缘计算集群的节点信息api接口

    1.接口描述接口请求域名:tke.tencentcloudapi.com。 查询边缘计算集群的节点信息 默认接口请求频率限制:20次/秒。 APIExplorer提供了在线调用、签名验证、SDK代码生成和快速检索接口等能力。您可查看每次调用的请求内容和返回结果以及自动生成SDK调用示例。 2.输入参数以下请求参数列表仅列出了接口请求参数和部分公共参数,完整公共参数列表见公共请求参数。 参数名称 必选 类型 描述 Action 是 String 公共参数,本接口取值:DescribeEdgeClusterInstances。 Version 是 String 公共参数,本接口取值:2018-05-25。 Region 是 String 公共参数,详见产品支持的地域列表,本接口仅支持其中的:ap-beijing,ap-guangzhou,ap-nanjing,ap-singapore。 ClusterID 是 String 集群id Limit 是 Integer 查询总数 Offset 是 Integer 偏移量 Filters.N

  • 腾讯云物联网智能视频服务(行业版)获取设备通道实时流地址(旧)api接口

    1.接口描述接口请求域名:iotvideoindustry.tencentcloudapi.com。 本接口(DescribeChannelStreamURL)用于获取设备指定通道实时流地址,地址是动态生成,如重新播放需要调用此接口重新获取最新播放地址。正常推流,如未设置对应录制计划,且180s无人观看此流,将会被自动掐断。 默认接口请求频率限制:20次/秒。 APIExplorer提供了在线调用、签名验证、SDK代码生成和快速检索接口等能力。您可查看每次调用的请求内容和返回结果以及自动生成SDK调用示例。 2.输入参数以下请求参数列表仅列出了接口请求参数和部分公共参数,完整公共参数列表见公共请求参数。 参数名称 必选 类型 描述 Action 是 String 公共参数,本接口取值:DescribeChannelStreamURL。 Version 是 String 公共参数,本接口取值:2020-12-01。 Region 是 String 公共参数,详见产品支持的地域列表。 DeviceId 是 String 设备唯一标识,必填参数

  • 腾讯云图片内容安全图片相册内容识别

    对于图片内容,在开通图片内容安全服务后,可直接调用图片内容检测(ImageModeration)接口,对图片相册(如QQ空间相册等)内容进行批量识别。 说明: 请在调用前确保目前账号至少拥有图片内容安全服务的访问权限,有关权限配置的相关信息,敬请参阅CAM授权指引文档。 若无法访问服务,则请开通服务/检查计费信息(主账号),或向管理员或主账号申请相应权限(子账号/协作者账号)。 步骤一:配置任务策略(可选)建议您使用配置任务策略,可根据业务需求配置识别策略,用于个性化服务体验。 说明: 腾讯云内容安全服务已预设有默认策略,如使用默认策略,可略过此步骤。 默认策略为天御多行业模型沉淀的策略配置,适用于大部分的内容安全需求。 前提条件 已获取腾讯云主账号或子账号。 登录账号已拥有图片内容安全服务的读写权限。 登录账号已开通图片内容安全服务。 操作步骤 登录 内容安全控制台,在左侧导航栏中,选择图片内容安全>策略管理。 在策略管理页面,单击创建策略,进入创建策略页面。 在策略信息填写页面,填写策略的相关信息,完成后单击下一步。参数说明:

  • nyoj 1129 Salvation(搜索)

    Salvation 时间限制:1000ms | 内存限制:65535KB  难度:3 描述        神秘瀑布镇是一个神秘的地方,那里有吸血鬼,狼人,巫师,二重身。Klaus(吸血鬼祖先)为了利用Elena的血液发展他的混血大军(吸血鬼&狼人),也来到了神秘瀑布镇。Stefan因为深爱着Elena,于是Stefan决定去唤醒吸血鬼猎人,来解救Elena。    吸血鬼猎人被封锁在一个迷宫里,这个迷宫有一种特性,只要进入就会失去方向感。于是Stefan想到一种方法,以左为标准(即优先左走),其次向前,向右,如果都无法走就向后走(即向右转两次)。他可以向上下左右四个方向的空格移动一个格,每次耗费1分钟。Stefan在得知你是一个有天赋的程序员后,决定让你判断他是否能找到吸血鬼猎人。 输入输入包含多组测试数据,第一行输入n,m(2<n,m<=100),接下来n行每行m个字符,第n+2行一个字符表示初始方向(EWSN)。 “.”代表空格,“#”代表墙,

  • vscode-oss 插件

    C/C++Snippets v0.0.15 hars CodesnippetsforC/C++ C/C++Snippets v1.0.6 ProgrammerShri SimpleAndFastcodesnippetsforCandC++ Chinese(Simplified)(简体中文)LanguagePackforVisualStudioCode v1.66.3 MS-CEINTL 11,888 LanguagepackextensionforChinese(Simplified) HexEditor v1.9.5 ms-vscode 2,958 Allowsviewingandeditingfilesinahexeditor MarkdownThemeKit v0.1.4 ms-vscode ThemeKitforVSCodeoptimizedforMarkdown.BasedontheTextMatethemes. 设置颜色主题 BracketLens v1.5.1 wraith13 Showbracketheaderonclosingbracket. 启用 BracketPa

  • n-1位数

      n-1位数 时间限制:3000ms | 内存限制:65535KB 难度:1   描述 已知w是一个大于10但不大于1000000的无符号整数,若w是n(n≥2)位的整数,则求出w的后n-1位的数。   输入第一行为M,表示测试数据组数。接下来M行,每行包含一个测试数据。输出输出M行,每行为对应行的n-1位数(忽略前缀0)。如果除了最高位外,其余位都为0,则输出0。样例输入 4 1023 5923 923 1000复制 样例输出 23 923 23 0复制   #include<iostream>#include<cstring>#include<string>usingnamespacestd; intmain(intargc,char*argv[]){ intm; cin>>m; while(m--) {       intw,i,a[6]; &nb

  • 利用jQuery无缝滚动插件liMarquee实现图片(链接)和文字(链接)向右无缝滚动(兼容ie7+)

    像新闻类的版块经常要求一条条的新闻滚动出现,要实现这种效果,可以使用jQuery无缝滚动插件liMarquee。 注意:    1.它的兼容性是IE7+,及现代浏览器。    2.引用的jquery的版本最好是在1.9以上。 问题:   在实现突破链接滚动时,经常会遇到ul的部分li元素会换行 原因:   原因是li元素设置了margin-left或margin-right,或者是li里面的a标签设置了margin-left或margin-right,导致ul的宽度小于其所有子元素的宽度、margin、padding的和。 解决方法:   在js中手动设置ul的width即可。 下面代码包括文字和图片链接的滚动: <!doctypehtml> <htmllang="en"> <head> <metacharset="UTF-8"> <title>利用jQuery无缝滚动插件liMarquee实现图片(链接)

  • Python之编程基础(编程语言分类)

    一、编程语言简介 编程语言主要从以下几个角度进行分类,编译型和解释型、静态语言和动态语言、强类型定义语言和弱类型定义语言。 1.编译型跟解释型 编译型,其实他和汇编语言是一样的,也是有一个负责翻译的程序来对问我们的源码进行转换,生成相对应的可执行代码。这个过程说的专业点儿就称为编译(Compile),而负责编译的程序自然称为编译器(Compile)。如果我们写的程序代码包含在一个源文件中,那么通常编译之后就会直接生成一个可执行文件,我们就可以直接运行了。但对于一个比较发杂的项目,为了方便管理,我们通常吧代码分散在各个源文件中,作为不同模块来组织。这是编译各个文件时就会生成目标文件(Objectfile)而不是前面说的可执行文件。一般一个源文件的编译都会对应一个目标文件。这些目标文件里的内容基本上已经是可执行代码了,但由于只是整个项目的一部分,所以我们不能直接运行。待所有的源文件编译都大功告成,我们就可以最后把这些半成品的目标文件打包成一个可执行文件了,这个工作由另一个程序员负责完成,由于此过程好像是把包含可执行代码的目标文件连接装配起来,所以又称为链接(Link),而负责链接的程序就叫

  • OTB(visual tracker benchmark) 的基础环境配置

    OTB是我们tracking领域常常用到的一个评估数据集,常用的有OTB50(2013年)和OTB100(2015年),下面就来演示一下如何让一个tracker(通常是一个文件夹的形式)在下载下来之后能成功运行于OTB-2013的平台上。 原料:1、matlab(有时候会涉及到matconvnet的使用,matlab尽量用新一点版本的) 2、OTB-2013平台(http://cvlab.hanyang.ac.kr/tracker_benchmark/benchmark_v10.html) 3、sequences(测试的视频集,需要一个个视频点进去下载,最后一起放到一个命名为sequences的文件夹中)(http://cvlab.hanyang.ac.kr/tracker_benchmark/datasets.html) 一、OTB框架基本介绍  在解压完压缩包之后我们得到一个名为tracker_benchmark_v1.0(这里我重命名为tracker_benchmark_test)的文件夹,再把下载的测试视频集放在sequences的文件夹中,将其一起放在命名为OTB的

相关推荐

推荐阅读