如何实现一个可以用 await 异步等待的 Awaiter

.NET 和 C# 共同给我们带来的 async/await 异步编程模型(TAP)用起来真的很爽。为了实现异步等待,我们只需要在一切能够能够异步等待的方法前面加上 await 即可。能够异步等待的最常见的类型莫过于 Task,但也有一些其他类型。即便有些耗时操作没有返回可等待的类型,我们也可以用一句 Task.Run(action) 来包装(同步转异步 - 林德熙 中也有说明);不过副作用就是 Run 里面的方法在后台线程执行了(谁知道这是好处呢还是坏处呢 ^_^)。

问题就在于,有些“耗时”操作根本就无法放入后台线程,典型的莫过于“耗时”的 UI 操作。本文将通过实现一个适用于 UI 的可等待类型来解决这种 UI 的“耗时”等待问题。

用 AppContext 解决类库的更新兼容问题

还记得微软在 Mitigation: Pointer-based Touch and Stylus Support 中告诉大家如何在 .NET Framework 4.7 中迁移 WPF 的触控到基于 Pointer 消息?记得关键的 <AppContextSwitchOverrides value="Switch.System.Windows.Input.Stylus.EnablePointerSupport=true"/> 这一句吗?

有没有好奇为何这一句话能用来控制微软基础类库中某一块功能的行为呢?阅读本文将了解微软为开发者提供的一套类库更新的兼容性解决方案——AppContext

彻底删除 Git 仓库中的文件避免占用大量磁盘空间

今天早上照常 git fetch --prune 获取大家写的代码,发现需要好长时间,但没怎么在意。直到下午小伙伴们才发现居然 fetch 了一个多 GB!询问才发现小伙伴 JAKE(其实我是在推荐博客)误传了 1.47GB 的垃圾文件。关键是等发现时,develop 分支上已经有 20+ 个基于这个文件的新提交了。

小伙伴说“不要紧,现在我已经删除它了!”突然一阵后背发凉,我们才 900M 的仓库肯定一下子飙到了 2000+M,必须马上处理之。

WPF/UWP 绑定中的 UpdateSourceTrigger

在开发 markdown-mail 时遇到了一些诡异的情况。代码是这么写的:

<TextBox Text="{Binding Text, Mode=TwoWay}"/>

然而在 TextChanged 事件之后延时执行了一些操作时,从 ViewModel 里拿到的值却始终是旧的。

阅读本文将了解其原因和解决办法。