Web Analytics
yangyang

码农兼一个普普通通小青年

All Posts in 2020


C#设计模式之命令模式

命令模式(command)简单来说就是将一系列的请求命令封装成对象,而不是直接调用真正执行者的方法,真正的执行由这个封装好的对象来执行,这样比较好扩展。比如我们在应用里面,经常会用到复制粘贴操作,这个操作可以由主菜单下面的按钮发出,也可以由快捷工具栏的按钮发出,也可以由快捷键Ctrl+C、Ctrl+V产生,这些不同的请求者发出的改变行为是一样的,如果各自都直接进行操作,就会使得代码逻辑重复,并且在执行一些撤销Undo或者重做Redo操作时就比较难以实现。    另外,在一些应用场景下,我们需要记录修改之前的值,以便于事后进行审计,或者回滚到之前的值等等。这种普通的直接对对像进行修改或者执行某种逻辑的方式,就无法扩展我们自定义的逻辑,比如日志、审计等等。 场景     假设我们需要对一个允许透支的银行账户进行建模,这个对象包含了两个方法,存款Deposit和取款Withdraw操作。 …

CQRS Command Pattern Design Pattern

C#设计模式之职责链模式

在软件开发中,我们通常会遇到一种场景,比如某个请求,会依次经过系统中的很多个模块来处理,如果某个模块处理不了,则将请求传递给下一个模块,比如在订单处理中,首先要经过用户校验,商品库存充足校验,如果不满足条件,返回错误,如果满足条件才会到下一步处理。     在ASP.NET Core里有middleware中间键的概念,每一个请求进来,都会经过一系列的Handler,这是一种职责链模式,每一个Handler都会决定是否处理该请求,以及是否决定将该请求传递给一下请求继续处理。     在.NET的委托中,也有一个委托链概念,当多个对象注册同一事件时,对象将委托放在一个链上,依次处理。     在JavaScript或者WPF的事件模型中,事件有冒泡和下沉,事件能够逐个向上级或者下级对象传递,每个对象都会决定是否会对该事件进行回应,或者终止事件的继续传递。     这些都是典型的职责链模式,责 …

Design Pattern Chain of Responsibility

C#设计模式之适配器模式

适配器模式,简单来说,就是将一个类的接口转换为另外一个类的接口,使得原本由于接口不兼容而不能一起工作的那些类能够一起工作。在现实生活中,这种例子也很多,比如我们如果买的是港行的电器,比如港版的iPhone,英版的原版树莓派,那么自带的充电器插头可能就是英标,在国内不能直接使用,国标的插头间距跟英标不兼容,所以,就需要一个适配器。 ▲ 不同标准插头的适配 还有个现实生活中的,比如我的车是个低配的绒布座椅,可以换更高级一点车的座椅,但是座椅的宽度可能不一样,那么就需要加一个滑轨适配器,一头把滑轨固定到车子上,一头就可以连接新更宽的座椅。 ▲ 不同宽度汽车座椅的兼容安装 还有个更有意思的图,下面这个😂。 ▲ 汽车到铁轨转换器,图片来自 https://refactoring.guru/ 场景 现在来说说软件开发中的一些场景,假设我们有一个基础绘 …

Design Pattern Adapter Pattern

游鱼之乐与庄子美学

庄子与惠子游于濠梁之上。庄子曰:“儵(shū)鱼出游从容,是鱼之乐也。” 惠子曰:“子非 鱼,安知鱼之乐?”庄子曰:“子非我,安知 我不知鱼之乐?” 惠子曰:“我非子,固不知 子矣;子固非鱼也,子之不知鱼之乐,全矣。”庄子曰:“请循其本。子曰‘汝安知鱼乐’ 云者,既已知吾知之而问我,我知之濠(háo)上也。”——《庄子·秋水》 我们耳熟能详的“子非鱼,安知鱼之乐?”就出自2000多年前庄子和惠子在濠河上的这场辩论,惠子的这句“子非鱼,安知鱼之乐”,我们通常用为,“别人不是我,所以不能理解我的欢乐和痛苦。” …


C#设计模式之桥接模式

在软件设计中,有一个很常见的问题是“状态空间爆炸”(state space explosion),即同一个对象的多个不想关的实体,用来表示所有可能的状态时,就会出现笛卡尔乘积式的问题。比如,假如我们有不同颜色的红色、蓝色(状态1)不同形状的(状态2)圆形、矩形对象,就要写四个类,比如RedSquare、BlueSquare、RedCircle、BlueCircle。如果增加一种形状,就要增加2个类,增加一种颜色,也要增加2各类。 我们要做的其实就是把一个事物的两个方面“组合”在一起,有多种方法能实现这一点,例如,如果颜色是一个简单特性,我们可以将颜色定义为枚举,如果颜色是可变属性、字段或行为我们就不能把他定义为枚举了。如果硬要这么做,要么代码里会出现很多if..else或者switch,这些分支语句里包含了其他一些不想关 …

Design Pattern Bridge Pattern

C#设计模式之享元模式

Flyweight,fly是苍蝇的意思,拳击里有个“蝇量级”,翻译也是“flyweight”,在设计模式中,Flyweight被翻译成了“享元”,意思是“共享元素”。在一些需要大量小的对象的应用场景,如果想要减少内存占用,可以考虑享元模式。下面举两个例子说明。 Example 1:人名的存储 比如,在英语国家,有很多人叫“John Smith”,如果我们在系统里,就要存储这个名字很多次,那么就需要很多额外的内存来存储相同的名字。相反,如果我们能够只存储某个名字一次,然后其余的都引用这个名字,这样就会节省很多空间。 再比如,可能“Smith”这个姓有很多人用,那么就可以将名字“John”和姓& …

Design Pattern Flyweight Pattern

C#设计模式之装饰模式

假设我们要扩展同事编写的某个类的某些功能,怎样在不修改类的前提下,增加新的功能呢?有一种方法是使用继承,编写一个继承自该基类的子类,然后添加新的方法,或者重写父类里面的某些方法或属性。 问题在于,在有些情况下,并不能继承。最常见的是这个类无法继承,要么是我们编写的类,需要继承自其他类,而在C#里面,不允许多各类继承,再就是这类是封闭的Sealed,无法继承。 Decorator装饰模式,可以使得我们扩展已经存在的类,而不需要修改已经存在类的代码,并且避免了继承导致产生过多子类。下面用一个例子来说明装饰模式。 自定义字符串构造器 假设我们要做一个代码生成器的功能,需要扩展StringBuilder,来增加缩进功能。首先想到的是直接继承自StringBuilder类,但是出于安全原因,这个类是Sealed封闭类,另外,还要保存当前缩进的级别用来给方法 …

Design Pattern Decorator Pattern Dynamic Decorator Static Decorator Decorator Composition

C#设计模式之组合模式

一个对象通常包含(composed)其他对象,或者说聚合(aggregate)其他对象。有一些方法能够让一个对象能够包含其他对象。最简单的是,让这个对象实现IEnumerable<T>接口,或者包含某个实现了IEnumerable<T>对象的public字段。 另外一种方式是继承自一些集合类,比如Collection<T>、List<T>等。因为继承自集合对象,所以对象本身也拥有了相关的存储特性。 因此,什么是组合模式?简单来说是让单个对象跟集合对象一样,让他们拥有相同的接口以及接口对象,这使得我们在使用这些接口及对象时,不需要关心该对象是单个对象还是集合对象。为了说明组合模式,下面举几个例子: 例1:图形对象集合 我们用过PowerPoint,在做PPT的时候,我们有时候选择一个对象,有时候选择多 …

Design Pattern Composite Pattern

C#设计模式之单例模式

单例模式(Singleton),故名思议就是说在整个应用程序中,某一对象的实例只应该存在一个。比如,一个类加载数据库中的数据到内存中以提供只读数据,这就很适合使用单例模式,因为没有必要在内存中加载多份相同的数据,另外,有些情况下不允许内存中存在多分份相同的数据,比如数据过大,内存容不下两份相同数据等等。 约定单例模式(Singleton by Convention) 这种方式有点“Too simple, Sometimes naïve”,他就是提示使用者,我是单例,不要重复初始化我,比如: public class Database { /// <summary> /// 警告,这是单例,不要初始化多次,否则,后果自负. /// </summary> public …

Design Pattern Creational Patterns Singleton

C#设计模式之原型模式

Prototype模式为创建型模式,翻译为原型模式。这种模式在生活中随处可见,很多产品设计一般都不会从头开始,都是从上一个版本直接不停的迭代,比如手机界早前的诺基亚“科技以换壳为本”,以及汽车工业界的更新,一般是过一年一个小改版基本就是“facelift”,然后才是大换代。 在软件工程中亦是如此,在有些情况下,与其从头开始创建一个对象(比如工厂方法模式或者生成器模式做的那样),可以从之前预构造的对象或者直接拷贝原有对象,或者对原有对象简单修改来生成新的对象。 这就产生了原型模式的概念,通过对某个对象的拷贝,定制化从而得到新的对象,原型模式的核心是拷贝,这也是容易出现问题的地方。 深拷贝与浅拷贝 拷贝分为深拷贝(Deep copy)和浅拷贝(Shallow copy)之分,区分两者至关重要。下面来看例子,我们定 …

Design Pattern Prototype Pattern Deep Copy Shallow Copy Prototype Factory

C#设计模式之生成器模式

Builder模式是创建型模式,它用来构建比较复杂的对象,这些对象无法通过单一的构造函数来实现,比如要构造一个类似HTML这样的具有嵌套结构的对象,这个类或许由其他几个类或者对象构成,或者具有一些特殊的构建逻辑。 Builder这里翻译参照GoF翻译为生成器模式,通常用来建造复杂的对象,下面用几个例子来说明,这些例子只是用来说明生成器模式,在实际应用中还要考虑其他因素。 场景 假设我们需要构建一个组件用来显示web页面。一个Web页面可能包含一个或者多个段落,或者其他组件,要构建一个段落,通常可以简单用字符串拼接,比如下面这个代码就构建了一个p段落。 var hello = "hello"; var sb = new StringBuilder(); sb.Append("<p>"); sb.Append(hello); sb. …

Design Pattern Builder Pattern Creational Patterns

C#表达式树:用表达式树替代反射

在动态调用对象方法方面,可以使用重构。但是在速度方便,重构比直接调用方法要慢很多,这里有两篇文章Expression Tree vs reflection,Again on Expression Tree vs Reflection 对比了表达式树和重构,以及 用lambda表达式树替代反射 这篇文章,在一些场景下,我们可以直接使用表达式树来代替重构。 本文将以Fix框架源码来说明,在一些特定场景下使用表达式树来替代反射能达到的奇妙效果和优点。 什么是FIX协议 FIX(Financial Information eXchange)金融信息交换协议是一种主要用于证券交易过程交换的公开协议,它定义每条交易信息的内容和格式,这些信息内容与证券交易流程相对应,以保证交易信息安全准确地传送。FIX主要用于在各类参与者之间建立起实时的电子化通讯协议。 FIX协议 …

Lambda Expression Expression Trees Fix QuickFixn Reflection

C#表达式树:构建动态查询

前文介绍了C#中表达式树的基本知识,在实际中,表达式树有很多用法,这里举几个例子,说明如何使用表达式树构建动态查询,从而扩展LINQ的查询方法。 在LINQ中,只要数据源实现了IQuerable<T>接口,表达式树就可以用来表示结构化查询。比如,LINQ提供了用来查询关系数据源的IQueryable<T>接口的实现,C#编译器在执行这类数据源查询时,会在运行时生成表达式树,然后,查询会遍历表达式树的数据结构,然后将其转换成针对特定数据源的合适的查询语言。 下面的几个例子演示了如何使用表达式树动态生成查询。 Example 1:动态生成Where和OrderBy 这个例子是MSDN上的例子,平常在C#中我们一般直接写LINQ代码,比如下面这个: companies.Where(company => (company. …

Lambda Expression Expression Trees Build Dynamic Query Safe Databinding

C#表达式树:基本用法

表达式树使用一种类似树的结构来表示代码,它的每个节点都是一个表达式,比如方法调用和x<y这样的二元运算等。我们可以对表达式树的内容进行编辑和运算,这样能够动态修改可执行代码,以及动态创建查询等。我们可以使用匿名lambda表达式或者C# API来创建表达式树。 这一系列文章,主要是对C#表达式树的一种总结,基本知识参考MSDN的内容 这部分内容可以直接到MSDN上查看,后面的几篇文章主要分享一下,在工作中碰到的应用到表达式树的部分,谨做为记录和分享。 生成表达式树 通过lambda表达式创建表达式树 可以通过将lambda表达式赋值给Expression<TDelegate>类型的变量,编译器可以自动生成创建该lambda表达式的表达式树。C#编译器只能从lambda表达式生成表达式树,只能是单行lambda表达式,不能解析多行 …

Lambda Expression .NET Core Expression Trees

.NET Core IoT破解PS2通讯协议

之前使用315MHZ可以进行远程控制,但是那个只有4个按钮,理论上只能控制4个变量的输入,并且偶尔信号还会串,所以需要探索其他远程控制方式。 PS2是Sony PlayStation2游戏机的遥控手柄,它采用的是2.4G无线通讯技术,有效控制范围能达到10米。恰好有人已经破解了通讯协议,使得手柄能够接到其他器件上遥控使用,比如这个叙利亚战场上使用PS2手柄控制的遥控机枪,我们这里只是简单的用在智能小车上,当然可以扩展到很多需要控制的地方,他的特点是性价比非常高(只要几十块钱就能买到一套山寨的控制器和接口,正版Playstation 2是不可能这个价格的,但是功能一点不差),而且按键丰富,方便扩展。 PS2手柄介绍 PS2手柄和接收器如下图: ▲ PS2 手柄和接收器 手柄,主要用来发送按键信息,接收器与主机相连(主机可以是树莓派,也可以是 …

IoT .NET Core PS2Controller

ASP.NET Core SignalR入门(三):后台服务及Chrome插件

前文介绍了如何通过SignalR将捕获到的摄像头信息,通过Streaming的方式传输到客户端。在PiMonitor例子中,作者在后台通过SignalR后台服务的方式,隔一段时间获取图像帧,然后连接Azure的认知服务来判断Baby是否在哭,从而向客户端触发提醒,这里就用到了SignalR的后台服务以及涉及到了开发Chrome插件来作为SignalR的客户端,下面逐个介绍。 SignalR后台服务 要在后台长期运行,并且能够通过SignalR向客户端发送消息,就需要用到SignalR的后台服务(background service)。ASP.NET Core承载SignalR后台服务,跟承载SignalR的Hub相似。只需要在ConfigurationServices中AddSignalR以及AddHostedService中注册需要的后台服务类. public …

SignalR ASP.NET Core SignalR Real-time App Hub Chrome Extension Background services

ASP.NET Core SignalR入门(二):生命周期及流式处理

上文介绍了Signal的基本知识,接下来介绍一下SignalR里面对象的生命周期以及流式处理,这两个比较重要的概念在前文开头的树莓派监控例子中有用到并且比较重要。 功能设计 树莓派监控PiMonitR这个项目包含了几部分内容,首先是如何获取摄像头数据流,然后通过SignalR,传输到客户端展示拍到的内容,并且客户单能够控制开始监控和停止,本文将实现这一功能。界面设计如下: ▲ 摄像头监控页面 界面如图所示,有两个按钮,Start Streaming点击之后,就可以通过流式数据传输从服务端传输到页面上来,Stop Stream会停止数据传输。下面是一个image标签,收到传输过来的流式数据之后,将image标签的src属性设置为接收到的数据。 在 树莓派监控PiMonitR 例子中,使用了MMALSharp - Unofficial C# …

SignalR ASP.NET Core SignalR Real-time App Hub RPC Streaming

ASP.NET Core SignalR入门(一):基础部分

之前在玩树莓派的时候看到一篇文章,Real Time Baby Monitoring from Raspberry PI using SignalR Streaming and Cognitive Vision Service, 主要内容是一位奶爸,用树莓派的默认的摄像头,监控摇篮中的Baby,通过SingalR,连接Azure的认知服务,如果检测到小孩哭,则提醒,然后可以查看监控。这里面有几个要点,首先是如何从树莓派的摄像头获取图形帧以及如何将树莓派上的图像帧展现出来。这里面最主要的就是涉及到了SignalR的内容,于是我学习了一下,以下是简单的学习笔记,都是参考官方文档的。如果你可以看英文,建议直接看 Introduction to ASP.NET Core SignalR MSDN上的相关文档,我这里只是做个笔记。 什么是SingalR ASP.NET Core …

SignalR ASP.NET Core SignalR Real-time App Hub RPC

.NET Core IoT使用TB6612FNG驱动直流电机

在开发树莓派小车时,需要使用树莓派来控制直流电机,树莓派无法直接驱动直流电机,需要使用直流电机驱动芯片,最常见的有L298N,比如一般的TT马达用这个驱动就足够,但是如果是大功率电机,它的发热量和死区都比较大,因为我买的小车是大功率直流电机,所以使用的是TB6612FNG驱动芯片,它是东芝的芯片,能驱动两个直流电机,或者并联四个直流电机(左前和左后并联,右前和右后并联)。本文介绍如何使用TB6612FNG来驱动直流电机。 TB6612FNG驱动芯片 TB6612FNG驱动芯片结构如下图: ▲ TB6612FNG结构图 我买回来,实物是这样的,体积很小。 ▲ 装车图 针脚很多, 对照TB6612FNG结构图,各针脚功能如下。 左边针脚 功能 右边针脚 功能 PWMA A电机控制信号输入 VM 电机驱动电压输 …

IoT Raspberry Pi .NET Core TB6612FNG DCMotor

树莓派4B安装Raspberry Pi OS系统遇到的问题和解决方法

在前面的一篇文章中,描述了如何在树莓派3b+上安装ubuntu 64位系统,因为官方还没有发布正式版的64位系统,所以只有安装第三方系统,但是开发过程中会碰到各种奇怪的问题,比如缺少rasp-config,需要自己安装;比如gpio权限问题,每次重启都要重新赋权;比如通过WIFI SSH登陆时时不时WIFI会断开不稳定;比如树莓派官方摄像头无法驱动等等。所以在做需要用到GPIO,摄像头这些硬件通信的时候,安装官方的树莓派系统。 最近又买了一个树莓派4B,原因是树莓派3B+我在做驱动直流电机实验的时候,使用的是面包板的电源线改造来的,他的输出电压是12V1A,是个DC头,我买了个DC转换头,引出了正极和负极,然后连上杜邦线,当时这两根线是带电的,我在操作的时候,不小心正极碰到了树莓派3B+的电路板,当时就看到了有火花,虽然当时树莓派没通电,但悲剧依旧发生了,我的树莓派3B+永远 …

IoT Raspberry Pi .NET Core

.NET Core IoT 驱动SSD1306 I2C显示器

本篇文章严重参考阿迪王的 Windows 10 IoT: How to Drive an SSD1306 I2C Display 这篇文章,我的传感器都是参照该博客来购买的。在进行以下实验时,最好保证树莓派安装的是官方系统。我之前安装的是64位Ubuntu 20系统,但是在需要访问I2C接口,或者访问树莓派官方摄像头,红外传感器发送和接受,以及本文的SSD1306显示时,总会遇到各种各样的问题。所以我重新将系统换成了官方32位系统以及32位.NET Core运行时,这对于Visual Studio开发来说没有变化,依旧发布后,拷贝到树莓派上即可运行,不需要关注32位或者64位。 SSD1306 I2C OLED显示器 SSD1306 I2C OLED显示器分辨率为128×64,也叫12864屏,SSD1306为其显示驱动芯片,长这样,各位在购买传感器的 …

IoT Raspberry Pi .NET Core SSD1306

.NET Core IoT 驱动 TM1637四位数码管

买了一个四位数码管,它长这样,有4个针脚,内部驱动芯片为TM1637,还有一种内部驱动芯片为74HC595,有5个针脚,千万要注意,不然就要996了,不过如果你买成了74HC585,可以参考阿迪王的这篇文章: 说回TM1637,这个模块是一个12脚的带时钟点的4位共阳数码管,只需要2跟线号线即可使单片机控制4位8段数码管,并且亮度8级可调。 接线 接线如上图,VCC接5V,GND接GND,CLK接GPIO19,DIO接GPIO26。显示是通过时钟CLK和DIO共同控制。 新建TLEDTM1637Driver类,用来封装显示模块,代码如下: public class LEDTM1637Driver : IDisposable { private byte[] Characters = { 0x3f, 0x06, 0x5b, …

IoT Raspberry Pi .NET Core TM1637 DigitTube

.NET Core IoT 315MHz 遥控器

我买了一个 315MHz 无线遥控收发模块,这种还有433MHz的。有了它你就可以进行各种遥控操作,比如可以用它遥控开启你家车库的门,停车库里的车位上的地锁(我估计也是这种,便宜稳定),可以用来遥控树莓派小车等,它长这样: ▲ 是不是觉得这遥控器,又丑又大😂 ▲ 实际他跟车钥匙差不多,还挺精致的😁 ▲ 还别说,这个遥控车钥匙的控制方式跟这个还挺类似,我看了下,他用的是434MHZ 左边是接收器,右边是遥控器,这遥控器,实际上跟车钥匙差不多大。如果不放对比,你可能觉得这东西又丑又大,我一开始也这么认为,买到手之后发现不大,看起来还挺精致。十来块钱就能买到还挺不错的。 左边的接收器,左上方ANT可以外接天线,板子上其实有个天线,我实测不外接天线,10米内仍然能接到信号。接收器上,从左到右依次接口为: VT,输出,只要遥控器任何一个按钮按下, …

IoT Raspberry Pi .NET Core 355MH Remote Control

.NET Core IoT 人体红外传感器

在前面的文章中,演示了如何通过GPIO的高低电平控制LED灯的亮起和熄灭,这篇文章介绍如何联动人体红外传感器来控制LED小灯的亮起和熄灭。 HC-SR501人体红外感应传感器 HC-SR501长下图这样,圆形的球是菲涅尔透镜.: 有三个插脚,VCC接树莓派5V电源接口, GND接树莓派GND接口,OUT是输出接口,接树莓派的GPIO口,感应到人体后,输出高电平,否则输出低电平。有两种信号输出模式 L不可重复,表示感应输出高电平后,延时时间一结束,输出将自动从高电平变为低电平。 H可重复,表示感应输出高电平后,在延时时间段内,如果有人体在其感应范围内活动,输出将一直保持高电平,知道人离开后才延时将高电平变为低电平。 调节方式就是上图左下角的黄色跳线,拔下就可以选择H或者L,默认为H。 这里由于传感器会向树莓派插口输出电压,尤其 …

IoT Raspberry Pi HC-SR501 PIR

.NET Core IoT Blink小程序

前面一篇文章说明了如何在Ubuntu上运行.NET Core程序,现在开始搭建第一个物联网小程序Blink。 配置GOPI接口权限 在开始访问GOPI时,需要设置树莓派的相关权限。一般都会告诉你使用使用sudo raspi-config命令,但是因为树莓派目前还没有正式版本的64位系统,我装的ubuntu,里面没有raspi-config,如果执行的话,会报Command Not found命令 ,所以需要安装相关模块,可以查看树莓派安装非官方系统没有raspi-config命令的解决方法。这篇文章。 安装完成之后,执行如下命令: ubuntu@ubuntu:~$ sudo raspi-config 就可以弹出主界面。 ▲树莓派设置主界面 ▲开启远程GPIO接口 开启之后,我们就可以开始针对GOPI编程了。 .NET Core代 …

IoT Raspberry Pi .NET Core Blink

树莓派3b+中安装64位ubuntu系统并设置.NET Core开发环境

很久之前买了一个树莓派3B+,放在那里吃灰😂,今天准备拿起来重新搞一下,一个是配置一下.NET Core开发环境,另外一个是玩一下.NET Core IoT。 ▲ 树莓派3B+ 在树莓派上安装64位Ubuntu 20.04 因为树莓派从3B+版本开始,支持64位系统,但是在树莓派官方网站上只提供了64位的beta版本系统。如果你买的是树莓派4 2G以上版本,那么最好安装64位系统,这样能充分利用内存。所以目前要安装64位系统,只有Ubuntu和Gentoo。 首先去Ubuntu官网下载针对Raspberry的64为系统。 下载下来的img文件,使用balenaEtcher工具烧录到树莓派的SD卡中。 使用Flash from file 选择img文件,中间选择树莓派的SD卡(需要读卡器),然后点击Flash!,烧录的过程中不要动读卡器 …

IoT Raspberry Pi .NET Core Ubuntu

Web API 3.0中日期类型的格式化设置

由于Web API快速迭代了好几个版本,在最新版本的格式化中,对于时间的格式化设置,记录一下。 Web API 3.0中的Json序列化,使用的是System.Text.Json这个序列化类。在不对其进行设置的情况下,对于日期格式,输出的内容形式是: 2020-06-30T06:16:38.62 默认使用System.Text.Json时的解决办法 在日期和时间中间有字母"T",这是一种IsoDateTime格式,有些时候,我们需要自定义格式,比如把中间的T去掉,以方便客户端使用。那么怎么办呢?那么就需要自定义数据类型转换。 public void ConfigureServices(IServiceCollection services) { services.AddControllers().AddJsonOptions(o =& …

WebApi

优化MATLAB读取数据的速度

有个C#程序每天实时落地了一些股票行情数据,为节省存储空间,数据是以二进制文件的方式存储的。现在要将这些数据提供给研究人员的MATLAB使用,需要编写一个C#的dll供MATLAB调用。 先说一下实时行情的格式。目前只需要用到存储数据里的,股票代码,涨停价,跌停价,最新价,时间,成交量,成交额,买一至买十的价格和数量,卖一到卖十的价格和数量这些信息,行情从9:25~15:00大概每3秒一条记录。 ↑ 典型的行情界面,上图里盘口只有5档,因为10档要钱😂 在C#里面,可以定义一个MarketData对象,表示某一时刻的行情,行情里面包含股票代码,买卖十档的价格和数量等等,MarketData 如下图,只列出了部分字段: public class MarketData { public string Symbol;//代码 …

Performance Optimizing Matrix MATLAB

如何正确对外暴露集合对象

我们在定义一个实体的时候,一般是不希望对外暴露其内部过多的成员信息的。尤其是一些集合信息,因为这些集合信息如果对外暴露不慎,就会破坏封装性,从而使得外部对象能够对其进行一些破坏性的修改。所以对外我们一般返回只读集合,这个问题在之前的文章不要对外公开泛型List成员中提到过。 问题的产生 下面以我们购物中的购物车为例来说明: public class Cart { private List<ProducItem> ProductItemsCollection; public Cart() { ProductItemsCollection = new List<ProducItem>(); } /// < …

IReadOnlyCollection

为什么听过很多道理,却依然写不好代码?

最近买了一本书《程序员修炼之道》,这书名起得跟葵花宝典一样😂,我一开始是拒绝的。就跟那些在畅销榜上的什么《阿弥陀佛么么哒》这种一听名字就反胃的书一样,畅销榜上的书都是好书吗?这年头花点钱就能上头条上热搜。写过代码的都知道,要想把某个东西排在前面再简单不过了,只要把数据库里这条记录的IsTop设为true就完事儿。这本书里的第18页说到: “永远不要低估商业主义的力量,网络搜索引擎仅仅把最热门的东西列在最前面而已,并不能说明这是你的最佳选择,而且内容提供商也可以花钱把他们的内容排到前面。书店有时候仅仅是把一本书摆在显著的位置而已,并不能说明这是一本好书,甚至不能说明这本书很流行,可能只是有人花钱把他摆在了那里”——《程序员修炼之道(第2版)》 非常有道理,现在的网络,为了讨好、迎合和吸引用 …


通过代理类解决异步回调信息缺失问题

问题的产生 在之前写的爬虫里,有把文章从博客园迁移过来的功能,除了文字之外,还有图片链接。需要把一篇文章里的图片找出来,然后下载,然后重新命名,再把新的名称更新到文章里。这里就涉及到一个问题,图片下载。 图片下载我这里用的是WebClient类: WebClient client = new WebClient(); client.DownloadFile(imageUri, localFilePath); 上面这个是同步方法,有两个参数,一个是图片url,一个是要存储的本地文件路径,包含文件名。很显然,不能用这个同步方法,因为它是阻塞的,下载一篇文章不可能一张图片一张图片的去下载。所以需要找到一个异步方法,同时要能提供图片是否下载成功相关信息。 C#里面提供了一些BeginXX和EndXX的异步方法,在其中的BeginXX方法中, …

Proxy Async Callback

推荐文章

写了一些文章,有一些自己比较满意,这些都是以系列的方式写的;还有一些写的比较随意,有凑数的嫌疑😂 (就像现在很多智能手机有很多摄像头一样,凑数的四摄🤣),这里列出自己相对比较满意的文章,方便查看。 1.Excel开发系列      这个是我当年在某财经公司做Office插件开发时的一些新得和总结,毫不谦虚的说,大概是目前网上关于Office插件开发比较全的文章,这方面资料比较少,这些文章是在工作中跟同事以及在网上不断查找探索的总结。总共写了十一篇。 浅谈Excel开发:一 Excel 开发概述 浅谈Excel开发:二 Excel 菜单系统 浅谈Excel开发:三 Excel 对象模型 浅谈Excel开发:四 Excel 自定义函数 浅谈Excel开发:五 Excel RTD函数 浅谈Excel开发:六 Excel 异步自定义函数 浅谈Excel开发:七 Excel 自定义任务窗体 浅谈 …

Excel Development Design Pattern SQLServer Performance Optimizing Data Structure Algorithm

一点读书笔记之二

之前看到一句话,说是“读书最好的目的在于,凭借自身阅读所构建的小世界,能以体恤式的温柔,消解自身的苦难。” 当然了,苦难不敢说,毕竟现在都小康社会了。更多时候其实是读书能够丰富自己的内心世界,任凭外面风吹雨打,内心能够岿然不动😂! 生活中存在很多的碎片时间,比如坐地铁啊,吃饭等饭的时候啊。这些时间不适合搞那些需要大量上下文切换的研究,所以比较适合看看文学作品,比刷微博微信快手抖音知乎之类的要好,这些东西越看越无聊,也没有许多有价值的信息,更多的都是一些垃圾信息。对于看啥书,大多时候选择书不能看排行榜,要选一些经过时间检验的,能够让人思考的书籍和文章,以前听过一个说法,说是只看死了的人写的书,这未免太偏激,不过也不是没有道理。书的好坏也不好辨别,还是要看个人,所以不太轻易推荐书,也许自己觉得好的,别人看来一般般。这里只是整理一下躺在草稿箱 …


使用EntityFrameworkCore对包含DbContext的类库生成迁移脚本

最近在学习EntityFramework Core的相关东西,其实数据库访问的方式有很多种比如有上古神器ADO.NET ,还有从java泊来的NHibernate等,当然还包括之前的Entity Framework,还有比较轻量级的Dapper等。关于数据访问,当然可以用手写SQL,然后用ADO.NET那一套来处理,但是都2020年了,这么搞显然不够高级,而且不够效率,最重要的是容易996。但是据我所知,并不是所有的公司都会去用ORM,就拿我曾经待过的还算比较大的一家公司来说,一般开发人员是接触不到DB的,对数据库的一些操作操作,有专门的DBA来管理,比如DBA会对某张表默认生成CRUD的存储过程,去调用就可以了,对于查询,一般的也是开发人员用ADO.NET 自己写SQL语句,最多就是把ADO.NET封装一下,提供给一般的开发人员使用。甚至一般的LINQ在有些公司都是禁止使用的 …

Entity Framework Core Migrations

SQLite入门及优化

SQLite是一个小型的关系型数据库系统,应用非常广泛,通常可以作为本地数据的临时存储,比如一些移动App使用SQLite作为本地存储,下面简单介绍一下SQLite的使用,以及注意事项。 在C#中使用SQLite比较简单。首先要去官网下载System.Data.SQLite 文件,这个是对SQLite3的C语言dll的.NET包装,根据当前的.NET版本以及操作系统是32位,还是64位,下载不同的程序集。当然,还可以在Visual Studio中,通过NuGet packages添加。 下载完成之后,在项目中引用System.Data.SQLite.dll就可以使用ADO.NET以类似访问SQL Server的方式访问SQLite了,当然,上面下载的安装包中,还包括System.Data.SQLite.EF6.dll,System.Data.SQLite. …

SQLite

关于新的个人博客

大概2011年的时候我在博客园上开通了一个主页,那个时候刚毕业,晚上下班回家无所事事,又不喜欢打游戏,就开始研究一些技术方面的东西,然后开始在上面写文章,之所以想着写文章,原来只是记录一下个人的一些经验或者遇到的问题的解决方法,方便以后自己查看,正所谓“好记性不如烂笔头”,很多东西如果不及时记录下来,时间长了也就会忘记。还有一部分文章是个人的一些读书笔记,比如看完之后,想着看能不能自己复述出来,这样也能检验自己是否真正的理解,我觉得书写对锻炼自己的表达能力和文字功底,是有一些帮助的。 从2011年到2016年期间,断断续续的写了大概100多篇,有一些是个人工作中遇到问题的总结,比如Excel插件开发系列,有一些是工作之余的一些爱好,比如Kinect开发,还有一些是读书笔记,比如算法和数据结构那些文章。当然,这些都是在工作不需要经常加班的条件下, …

.NET