walterlv

吕毅 - Windows 10 Developer

吕毅 - walterlv


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

吕毅 更新于 2017-10-30 22:01,发布于 2017-10-29 16:38

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

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

使用 Task.Wait()?立刻死锁(deadlock)

吕毅 更新于 2017-10-28 13:10,发布于 2017-10-27 23:54

最近读到一篇异步转同步的文章,发现其中没有考虑到异步转同步过程中发生的死锁问题,所以特地在本文说说异步转同步过程中的死锁问题。

为 Web 页面添加 iPhone 固定标签页的图标

吕毅 发布于 2017-10-28 00:16

我曾经将一个 Web 标签页固定到 iPhone 的主屏幕上,发现居然有一个图标。当时没有留意,可直到今天发现我的博客页面在我的 iPhone 主屏幕上显示一片空白后,才想起来原来还可以自定义图标。

使用 ExceptionDispatchInfo 捕捉并重新抛出异常

吕毅 更新于 2017-10-27 07:38,发布于 2017-10-23 22:22

当你跑起了一个异步线程,并用 await 异步等待时,有没有好奇为什么能够在主线程 catch 到异步线程的异常?

当你希望在代码中提前收集好异常,最后一并把收集到的异常抛出的时候,能不能做到就像在原始异常发生的地方抛出一样?

本文介绍 ExceptionDispatchInfo,专门用于重新抛出异常。它在 .NET Framework 4.5 中首次引入,并原生在 .NET Core 和 .NET Standard 中得到支持。

配置 legacyUnhandledExceptionPolicy 防止后台线程抛出的异常让程序崩溃退出

吕毅 更新于 2017-10-26 18:51,发布于 2017-10-16 20:52

如果你的程序抛了异常,你是怎么处理的呢?等待程序崩溃退出?还是进行补救?

如果是做 UI 开发,很容易就找到 Dispatcher.UnhandledException 事件,然后在事件中进行补救。如果补救成功,可以设置 e.Handled = true 来阻止异常继续让程序崩溃退出。但是,如果是后台线程抛出了异常呢?并没有 Dispatcher 可以用。所以我们就束手就擒让程序自己退出吗?

WPF 和 UWP 中,不用设置 From 或 To,Storyboard 即拥有更灵活的动画控制

吕毅 发布于 2017-10-26 12:55

无论是 WPF 还是 UWP 开发,如果用 StoryboardAnimation 做动画,我们多数时候都会设置 FromTo 属性,用于从起始值动画到目标值。然而动画并不总是可以静态地指定这些值,因为更多的时候动画的起始值和目标值取决于当前 UI 的状态。

本文中,我将将尽量避免设置 FromTo 值,让动画可以随时中断并重新开始,而中途不会出现突兀的变化。

UWP 中的 LaunchUriAsync,使用默认浏览器或其他应用打开链接

吕毅 更新于 2017-10-22 15:48,发布于 2017-09-25 00:39

古老的 Win32 应用启动其他程序太过方便,以至于一部分开发者都已经不记得 Windows 能通过关联协议(参见 桌面应用程序关联协议)的方式通过统一资源定位符(URI)来启动应用程序了。

转到 UWP 后,使用 URI 启动应用似乎成为了最推荐的方式。于是一句 LaunchUriAsync 就能解决大多数问题。

如何组织一个同时面向 UWP/WPF/.Net Core 控制台的 C# 项目解决方案

吕毅 发布于 2017-10-21 11:20

希望写一个小型工具,给自己和需要的人。考虑到代码尽可能的复用,我准备采用 .Net Standard 来编写大多数核心代码,并基于 .Net Core 编写跨平台控制台入口,用 WPF 编写桌面端 UI 入口,用 UWP 作为可上架商店的 UI 入口,然后用 Shared Project 共享 WPF 和 UI 的多数 UI 入口代码。

阅读本文将了解到如何在尽可能复用代码的情况下组织这样的 C# 解决方案。

安利一款非常好用的命令行参数库:Microsoft.Extensions.CommandlineUtils

吕毅 发布于 2017-10-21 09:44

命令行参数解析想必是每一个命令行程序都难以避开的工程。这工程可小可大,但每次都写始终是在浪费时间。而且,不同人实现也千差万别,使得不同的命令行程序命令参数传入的体验总有差异。

于是安利一款命令行工具库——Microsoft.Extensions.CommandlineUtils,微软出品,却符合当下各大主流命令行工具的参数体验;而且,代码非常简洁。我为此封装了一组基于反射调用命令的类,以至于实现复杂的命令代码也能非常简洁。

UWP 和 WPF 不同,ListView 中绑定的集合修改顺序时,UI 的刷新规则

吕毅 发布于 2017-10-20 08:14

ObservableCollection<T> 中有一个 Move 方法,而这个方法在其他类型的集合中是很少见的。由于 ObservableCollection<T> 主要用于绑定,涉及到 UI 更新,而 UI 更新普遍比普通的集合修改慢了不止一个数量级,所以可以大胆猜想,Move 的存在是为了提升 UI 刷新性能。

然而事实真是这样的吗?

深入了解 WPF Dispatcher 的工作原理(Invoke/InvokeAsync 部分)

吕毅 更新于 2017-10-19 21:13,发布于 2017-09-26 02:02

深耕 WPF 开发的各位程序员大大们一定避不开使用 Dispatcher。跨线程访问 UI 当然免不了用到它,将某个任务延迟到当前任务之后执行也会用到它。Dispatcher.Invoke、Dispatcher.BeginInvoke 是过去大家经常使用的方法,而 .Net Framework 4.5 中微软为我们带来了 Dispatcher.InvokeAsync 方法,它和前面两个有何不同?

阅读本文将更深入地了解 Dispatcher 的工作机制。

各个版本 Windows 10 系统中自带的 .Net Framework 版本

吕毅 发布于 2017-10-17 10:49

Windows 名称 Windows 版本 自带的 .Net Framework 版本
Windows 10 Fall Creators Update 10.0.16299 (1709) .Net Framework 4.7.1
Windows 10 Creators Update 10.0.15063 (1703) .Net Framework 4.7
Windows 10 Anniversary Update 10.0.14393 (1607) .Net Framework 4.6.2
Windows 10 November Update 10.0.15063 (1511) .Net Framework 4.6.1
Windows 10 10.0.10240 (1507) .Net Framework 4.6

出让执行权:Task.Yield, Dispathcer.Yield

吕毅 发布于 2017-10-14 17:18

Yield 这个词很有意思,叫做“屈服”“放弃”“让步”,字面意义上是让出当前任务的执行权,转而让其他任务可以插入执行。TaskDispatcherThread 都有 Yield() 方法,看起来都可以让出当前任务的执行权。

转义,解决花括号在 Jekyll 被识别成 Liquid 代码的问题

吕毅 发布于 2017-10-13 00:08

DependencyProperty.UnsetValue 的正确打开方式合并 Jekyll 多种类型的页面 这两篇博客中,我都遇到了代码中的花括号被 Jekyll 识别为 Liquid 代码的问题。

合并 Jekyll 多种类型的页面

吕毅 发布于 2017-10-12 23:48

以前胡思乱想时,有时会讲给小伙伴们听,有时会将想法在微信上发给自己,但多数时候是没有后文的,让胡思乱想烂在脑中。还好多数时候我记得,就像我亲自记得 3 岁时候的一些故事一样。

但今天大脑被一些凌乱的事情撑爆了,心情极度低落。正好近期学着写博客,于是想把一些胡思乱想的事情写在自己的站点上。

阅读本文,将学到如何用 Jekyll 做多种类型的页面,并在首页的列表中将这些不同种类的页面合并按日期排序。