使用TreeView

上次说到了TreeView具有递归的结构,而在WPF中是数据驱动界面,这就要求我们的数据源也具有一定的递归结构

数据的准备

按照数据源是否可以继续展开下去,我们将数据源定义为两个ViewModel:TreeNodeVM,TreeLeafVM,其中TreeNodeVM作为树的中间节点出现,其下可继续出现中间节点和叶子节点,TreeLeafVM作为树的叶子节点出现,不能再出现其他节点。TreeNodeVM中的子节点的个数是不定的,所以应该由集合表示。而TreeNodeVM的子节点可能是TreeNodeVM和TreeLeafVM的任意一种,这就需要他们有一个公共的父类。这给我们如下的数据定义:

阅读全文

ItemsControl

有时需要呈现一组逻辑上平级的控件,他们可以是一个列表,也可以是一个网格;可以横向排列,也可以纵向排列;数量可以固定,也可以按需加载;普通控件的组合无能为力。所以,我们需要新的工具。ItemsControl应运而生。

阅读全文

日常新需求

新的需求又来了。这次是程序在编译后6个月拒绝启动。BETA性质的软件都有类似的需求。但大部分软件要么是启动时检查更新,要么是联网判断是否过期。对于我们现在做的这个小工具太小题大做了。根据编译时间判断过期的需求看似奇葩,也是有点道理的。

阅读全文

背景

项目需求变更,需要从一份代码里编译出好几个不同的版本。编译和部署的复杂度都成指数增加,简单的Release构建搞不定了,写构建脚本迫在眉睫。

阅读全文

巨人的肩膀

新事物的产生总是与老事物有千丝万缕的联系。或是从中得到启发,或是对其全面改良。新事物的源头通常可以追溯到很久远的一些概念上。因此有了「站在巨人的肩膀上」 这样的说法。在程序设计里面,「巨人们的肩膀」 就是我们的应用程序使用的库了。踩在这些「巨人」们的肩膀上我们的程序才得以重见天日;为了实现一个库,有时候会使用到其他的库。我们所依赖的「巨人」又踩在了其他「巨人」的肩膀上,把依赖关系变成了树状结构,我们的程序处在根节点。

扯远了:)

阅读全文

值类型与引用类型

C#中的类型分为引用类型和值类型。使用struct或enum关键字修饰的类型定义是值类型,使用class或delegate关键字修饰的类型是引用类型。引用类型和值类型各有限制,分别适用于不同的场景。不同于C++,C#中的值类型只能分配在栈上*1,引用类型只能分配在GC堆上。C#中的GC是精确式GC,这就对GC堆上的指针有了一些要求。这是引用类型有开销的原因之一。

Sync block index 与 Type object pointer

读过C# vir CLR的同学会知道,引用类型的开销是Sync blockindex和Type object pointer。他们的长度是都是一个字长。即在32位CLR上是4字节,在64位CLR上是8字节。Sync block index在CLR中是用于实现lock,Monitor等线程同步原语,Type object pointer是指向当前对象运行时类型信息的一个指针。Sync block index与Type object pointer只在CLR层面存在,对C#程序来说是透明的。但是CLR将它们暴封装后露C#,例如线程同步原语和反射API。

阅读全文

Preface

说来惭愧,直到近几天才明白了一点面向对象设计的。给我带来启发的是SOLID中的D,它代表Dependency Inversion(依赖反转)。尽管写/背定义很无聊,但我还是想写一下依赖反转的核心

阅读全文

废话

BUG是任何软件都会遇到的问题。它通常是开发人员考虑问题不全面而埋下的隐形炸弹,在条件合适的时候就会爆炸;开发自己埋BUG往往比较容易除错,因为代码都是自己写的,定位问题后git blame一下就可以甩锅了;而程序依赖项里的BUG则排查起来则让人一筹莫展,尤其是在没有足够多信息的情况。

面对来自客户和QA的压力,绞尽脑汁仍无法定位问题开发们只能找借口了🤣

  • It’s a feature,not a bug.
  • That’s the design decision, so not a bug

我以前也遇到框架出问题的情况,不过都是自己改代码改出来的,倒也不是很难排查。但这次挖出来的BUG就完全不一样了

阅读全文

问题描述

公司的APP,在断网后进行一个10秒的倒计时操作,每秒钟都会尝试重新联网。当秒数到0时又重新开始计时,倒计时在用户退出程序或者连上网络结束。

按理说是个很简单的Case。QA却报过来个BUG,说APP状态由

联网->断网->联网->断网

变化后,倒计时的秒数变为

9 3 8 2 7 1

变得不连续了。

阅读全文

HttpClient是随着.Net framework 4.5一起发布的现代Http库。比起WebClient,HttpClient最大的优点就是 加入了C#5中的async/await异步方法的支持。async/await的坑暂且不表,今天就来说一说这个HttpClient

HttpClient的坑

HttpClient实现了IDisposable接口,很多小伙伴一看到IDisposeable接口就纷纷把HttpClient套在了using里边

//bad httpclient usage
using(var client = new HttpClient())
{
    //do stuffs
}

这种用法是错误的.HttpClient在设计之初被设计为一个可重用的对象,它的生命周期应该与应用程序相一致.上述错误的用法每发起一个请求就会创建一个新的HttpClient,并且在收到回复之后立即把HttpClient dispose掉。众所周知TCP连接在真正断开之前会有几分钟处于CLOSE_WAIT状态。这个状态下TCP链接并没有真正断开。短时间内大量发出Http请求会使系统可用的端口急剧消耗。

阅读全文