WinAppSDK / WinUI3 项目无法使用 SystemEvents 的问题
SystemEvents 是一个开发 win32 窗口项目很常用的类,其中封装了一些常用的系统广播消息。在 WinUI3 项目中,SystemEvents 事件经常无法触发,简单排查了一下原因。
SystemEvent 内封装了一个线程和一个窗口,通过窗口消息在内部线程上调用事件,内部使用了 SystemEventInvokeInfo 对象来保存委托,RaiseEvent 方法遍历调用保存的 SystemEventInvokeInfo.Invoke 方法来触发事件。
public SystemEventInvokeInfo(Delegate d)
{
_delegate = d;
_syncContext = AsyncOperationManager.SynchronizationContext;
}
// fire the given event with the given params.
public void Invoke(bool checkFinalization, params object[] args)
{
try
{
// If we didn't get call back invoke directly.
if (_syncContext == null)
{
InvokeCallback(args);
}
else
{
// otherwise tell the context to do it for us.
_syncContext.Send(new SendOrPostCallback(InvokeCallback), args);
}
}
catch (InvalidAsynchronousStateException)
{
// if the synch context is invalid -- do the invoke directly for app compat.
// If the app's shutting down, don't fire the event (unless it's shutdown).
if (!checkFinalization || !AppDomain.CurrentDomain.IsFinalizingForUnload())
{
InvokeCallback(args);
}
}
}
我们可以注意到 SystemEventInvokeInfo.Invoke 判断了 _syncContext 变量,_syncContext 变量在 SystemEventInvokeInfo 构造时捕获,Invoke 时使用 _syncContext.Send 方法调用。
/// <summary>
/// DispatcherQueueSyncContext allows developers to await calls and get back onto the
/// UI thread. Needs to be installed on the UI thread through DispatcherQueueSyncContext.SetForCurrentThread
/// </summary>
public class DispatcherQueueSynchronizationContext : SynchronizationContext
{
private readonly DispatcherQueue m_dispatcherQueue;
public DispatcherQueueSynchronizationContext(DispatcherQueue dispatcherQueue)
{
m_dispatcherQueue = dispatcherQueue;
}
public override void Post(SendOrPostCallback d, object state)
{
if (d == null)
throw new ArgumentNullException(nameof(d));
m_dispatcherQueue.TryEnqueue(() => d(state));
}
public override void Send(SendOrPostCallback d, object state)
{
throw new NotSupportedException("Send not supported");
}
public override SynchronizationContext CreateCopy()
{
return new DispatcherQueueSynchronizationContext(m_dispatcherQueue);
}
}
而 WinUI3 的 UI 线程的默认 SynchronizationContext 为 DispatcherQueueSynchronizationContext,简单查看源码可以发现 DispatcherQueueSynchronizationContext.Send 并未实现,而是直接抛出了异常,所以从 UI 线程注册的 SystemEvents 事件默认是不会触发的。
解决方案也很简单:
SystemEvents.InvokeOnEventsThread(() =>
{
// 不需要设置,因为默认就是null
//SynchronizationContext.SetSynchronizationContext(null);
SystemEvents.DisplaySettingsChanged += (s, a) =>
{
Debug.WriteLine("DisplaySettingsChanged");
};
});
我们借用一下 SystemEvents 的内部线程,在此线程上注册事件时 SystemEventInvokeInfo 捕获不到 SynchronizationContext,就会在 SystemEvents 内部线程上触发事件,自然就能正常触发了。
WinAppSDK / WinUI3 项目无法使用 SystemEvents 的问题的更多相关文章
- Vue项目无法使用局域网IP直接访问的配置方法
一般使用 vue-cli 下来的项目是可以直接访问局域网 IP 打开的,比如 192.168.1.11:8080 .但是最近公司的一个项目只可以通过 localhost 访问. 需要配置一下,才可直接 ...
- win10本地python第三方库安装成功,但是pycharm项目无法使用解决方案
一.背景win10本地python第三方库安装成功,但是pycharm项目无法使用解决方案如本地安装的python中的request库,在pycharm项目中居然无法使用,比较郁闷 pip list ...
- jhipster生成项目无法使用restful请求,报access_denied 403错误
写在前边: 我们的微服务是注册中心.uaa.gateway为基础,添加微服务应用,昨天下午在测试jhipster的增删改查,因为jhipster生成的代码都是restful的,好不容易找到网关配置的映 ...
- [转]关于MyEclipse下的项目无法使用BASE64Encoder问题的解决办法
[链接] http://blog.csdn.net/longlonglongchaoshen/article/details/75087616
- 解决Idea、WebStorm下使用Vue cli脚手架项目无法使用Webpack别名的问题
问题截图: 解决方案: 1.打开File --> Setting 窗口 2.搜索 Webpack 3.选择如下路径 问题解决
- 含有SilverLight项目的代码重用
很多时候,我们工程中不只是有SilverLight项目,然而我们想把其他的项目中的工具类,或者实体类复用到SilverLight项目中时,会发现SilverLight项目无法使用.这是个很普遍的现象. ...
- Hibernate项目里配置环境时,jar包配置不当会对测试结果产生影响。
问题情况: 如下图所示,该图中,显示了一堆错误的jar包.这是导致了Junit4测试通过了,数据库却没反应的原因. 原因: 之所以出现这种情况,eclipse其实已经告诉了我们原因.如下图所示,这些j ...
- 前段时间,接手一个项目使用的是原始的jdbc作为数据库的访问,发布到服务器上在运行了一段时间之后总是会出现无法访问的情况,登录到服务器,查看tomcat日志发现总是报如下的错误。 Caused by: com.mysql.jdbc.exceptions.jdbc4.MySQLNonTransientConnectionException: Data source rejected est
前段时间,接手一个项目使用的是原始的jdbc作为数据库的访问,发布到服务器上在运行了一段时间之后总是会出现无法访问的情况,登录到服务器,查看tomcat日志发现总是报如下的错误. Caused by: ...
- 导入maven项目出现 Unsupported IClasspathEntry kind=4
Unsupported IClasspathEntry kind=4 这个异常会导致项目无法使用spring ide启动 来自:http://blog.csdn.net/kongqz/article/ ...
- 发布报错:Error ITMS-90635 - Invalid Mach-O in bundle - submitting to App store
发布报错:Error ITMS-90635 - Invalid Mach-O in bundle - submitting to App store 昨晚上传项目到AppStore,报了这个错,纳尼! ...
随机推荐
- JS leetcode 有序数组的平方 题解分析,灵活运用Math.pow与Math.abs方法
壹 ❀ 引 郁闷的周一,晚上来做一道简单的算法题提提神,题目来自leetcode977. 有序数组的平方,题目描述如下: 给定一个按非递减顺序排序的整数数组 A,返回每个数字的平方组成的新数组,要求也 ...
- python 学习随笔1121
Python 数据处理几个好用又简单的库: json re string pandas 与系统交互: subprocess os
- Swoole从入门到入土(9)——TCP服务器[协程风格]
上一篇,我们一起初步接触了协程.我相信只有一节的讨论,很多小伙伴对于"协程"与"线程"的区分可能还有点模糊.我们这里以两者的比较作为本篇开头,进行一番比较. 首 ...
- Java Console类
用于从控制台设备读取字符信息,通常是文本和密码.尤其读取密码字符时是看不见的. 下面给出一个例子: import java.io.Console; /** * @author xusucheng * ...
- 超简单JSP人员信息管理系统(适合新手练手用)
自己以前闲着没事写的JSP小项目,适合刚学完JSP拿来练手的朋友. 源码地址: https://github.com/mudfish/userManager 项目说明: 软件需求: 开发工具:ecli ...
- virtualbox中给redhat安装增强功能
关于虚拟机中安装redhat请参考其他教程: 1.点击虚拟机菜单:设备--安装增强功能.... 2.ssh连接到redhat,执行以下操作: [root@rhel-server ~]# mount / ...
- Web流式下载数据时展示提示信息
以Web方式下载数据有多种场景: 1.服务端本身已经存在文件,此时只需要一个文件访问地址即可下载,比如:将文件URL设置为<a>标签的href属性即可,点击<a>标签就能立即触 ...
- 优雅使用前端枚举Enum,符合国标的那种!
01.什么是枚举Enum? 枚举Enum是在多种语言中都有的一种数据类型,用于表示一组特定相关的常量数据集合,如性别(男.女).数据状态(可用.禁用).垂直对齐(顶端.居中.底部).星期等.特点是数据 ...
- .net+bootstrap写的一个还不错的音乐网站
以前做的一款设计音乐网站,分享下. 技术用的是.net +sqlserver 大致的样子是这样的. 1.首页如下: 2.播放歌词页面如下:歌词自动滚动,且可悬停. 3.歌单信息页面如下: 详细页面如下 ...
- .NET Core 集成微信支付签名错误
.NET Core 集成微信支付签名错误 The provided data is tagged with 'Universal' class value '16', but it should ha ...