1
0

Index.md 4.7 KB

一些说明

代码的用户有三个:人、IDE、运行时,IDE介于人和运行时之间连接两者。

  • 开源矿工没有任何一行代码不开源(包括服务器代码),因为没有时间回答矿工的问题所以就更没有时间回答程序员的问题了,遇到问题可以找同事或者其他程序员解决,开源矿工再次肯定没有任何一行代码不开源。
  • 有些项目比如NTMinerDaemon直接引用了别的项目比如NTMinerlib的代码文件而不是引用整个NTMinerlib类库,这是为了消减依赖和共用代码,因为NTMinerlib中有更多NTMinerDaemon用不到的代码。
  • 开源矿工有大量的代码,大部分代码是为了造型为了将信息链条连贯出来避免跳跃避免魔术。
  • 挖矿客户端、群控客户端 共用了相同的类库,类库里面有些地方会根据程序类型的不同执行不同的逻辑,似乎是不应该共用类库,但将挖矿端和群控端看作是一个程序就行了。
  • 源码中到处都是接口,有些接口的意义可能只是为了让IDE帮助监管代码,消灭手误。
  • 名字叫*Root的类型都是静态类型,名字叫*Context的类型都不是静态类型。
  • 有些类型可以抽象为泛型比如命名为Edit*Command模式的类型,不使用泛型而使用显式的类型是为了文档、集中信息、不隐藏信息、用.NET类的类型承载信息而不是用通用类型的属性承载信息。
  • 有些需求可以通过实现BCL类库中的通用接口表达,比如枚举ICoinSet集合中的ICoin元素的需求可以通过实现IEnumerable接口表达,但开源矿工不这么表达,同上也是为了文档、不隐藏信息,便于人和IDE查找和定位代码,便于转到代码的位置。
  • 开源矿工编程的模式很少传参除非确实是函数才传参,或着确定具有不变性的时候才传参(所谓不变性主要是运行时执行顺序的不变性),这个编程模式是面向一棵造型稳定的树形数据结构或者叫作用域编程的,或者叫面向空间编程,如果不借助空间思维脑子里没有系统的形状阅读代码可能会有困难。
  • NTMiner.Vms命名空间下的类型很多,不做进一步编排不做进一步归类,因为人要基于图形空间思维,人先找界面,通过界面模型上的Vm属性转到Vms命名空间下的具体模型而不是直接找Vm。
  • 每个视图类型(Window、Uc)都有一个命名为Vm的ViewModel属性,该属性不一定在运行时有用因为放置该属性的目的是便于人从视图导航到视图模型。
  • 确保不要在Xaml中构建任何ViewModel对象,确保视图类型(Window、Uc)的Vm属性不是通过转型它的DataContext得到的,从而避免访问Vm的时候访问到UI对象造成在非UI线程访问UI对象的异常。
  • 局部性是好事,但也有利弊,凡是有可能变化的事物在开源矿工中都具有唯一性,它们都挂载在VirtualRoot、NTMinerRoot、RpcRoot、AppRoot上,也就是说此类对象不会注入到当地也不允许当地持有对此类对象的引用,只允许在过程中(方法或函数)从Root根开始索引。
  • 新版本的C#语法不要求对只读属性声明private set访问器,这不是一个好特性,开源矿工不会使用这个语法,因为没有private set访问器的声明就没法在set上右键查找引用位置了。
  • 用属性不要用字段,因为字段上没有IDE提供的引用计数信息。
  • 数据常驻内存,数据在内存中列表、字典排布。内存中是存在形如Dictionary>类型的数据的,其中的List可能会直接以引用的形式返回给调用者,调用者拿到后可能会foreach,但List可能会在foreach期间被另外的线程修改,所以这里需要两点约定:1,使用数组传达不可变性;2,枚举List前应ToArray个快照,枚举快照。
  • 开源矿工运行时对内存空间的布置通常都是延迟到直到第一次行走进那个空间时才会布置那个空间,这很好理解因为布置内存的数据可能来自于磁盘或网络等IO,延迟布置可以加快开源矿工的启动速度。布置且只布置一次,所以会有个_isInited和_locker,需要注意的是某些内存集布置完成时会向总线报告布置完成事件,而别处对布置完成事件的响应中可能又会访问到这份刚刚布置完还没来得急将_isInited置为true的内存集导致死循环,这个死循环我线下开发时遇到过一次特此记录,解决办法很简单:确保在发布布置完成事件到总线上之前将_isInited置为true,为了保证这个确保所以整了一个SetBase抽象基类在基类中确保。