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,报了这个错,纳尼! ...
随机推荐
- Linux下磁盘管理工具:hdparm/iostat/parted/fdiisk/badblocks/smartctl/losetup/sg3_utils/sqinfo/smp_utils/udevadm
一.hdparm: hdparm可以检测,显示与设定IDE,SCSI,SATA,SAS硬盘的硬件参数, 如: hdparm -I /dev/sdc 可以获取sdc的硬件信息 ...
- python绘图总结
1 二维图像 1.1 二维曲线 plot(x, y, ls="-", lw=1.5, label=None) x, y:横坐标和纵坐标 ls:颜色.点标记.线型列表,如 ls='r ...
- Vue+SpringBoot+ElementUI实战学生管理系统-4.后端API编写
1.章节介绍 前一篇介绍了项目的表结构设计,这一篇编写后端API,需要的朋友可以拿去自己定制.:) 2.获取源码 源码是捐赠方式获取,详细请QQ联系我 :)! 3.项目截图 登录页 列表操作 动态图 ...
- nginx配置反向代理缓存
说明 最近运维一个网站里面含有不经常变化的小图片,而每次请求都需要调用file接口获取不太合适.所以就想利用nginx的反向代理缓存来减轻服务接口的请求压力. 工作原理 Nginx反向代理缓存,当客户 ...
- Jsp+Servlet实现文件上传下载(一)--文件上传
文件上传和下载功能是Java Web必备技能,很实用. 本文使用的是Apache下的著名的文件上传组件 org.apache.commons.fileupload 实现 下面结合最近看到的一些资料以及 ...
- 阿里云 SMS 短信 Java SDK 封装
Github & Issues: https://github.com/cn-src/aliyun-sms 官方文档:https://help.aliyun.com/document_deta ...
- [Rust] 命名习惯
[Rust] 命名习惯 通用习惯 CamelCase: 首位是大写字母的单词,没有分隔符: snake_case: 使用下划线作为分隔符,小写单词: SCREAMING_SNAKE_CASE: 使用下 ...
- Spring + JAX-WS : ‘xxx’ is an interface, and JAXB can’t handle interfaces 错误解决方法
错误栈 Caused by: com.sun.xml.bind.v2.runtime.IllegalAnnotationsException: 2 counts of IllegalAnnotatio ...
- 【Azure 应用服务】Azure App Service多实例中,出现某一个实例CPU居高不下的情况,如何重启单个实例呢?
问题描述 在使用App Service服务中,当多实例中,其中一个实例出现高CPU,高Memory的情况,为了尽可能少的影响正在运行的应用,需要单独重启某一个实例的情况下,如何手动操作呢? 问题解答 ...
- 从零开始搭建Springboot开发环境(Java8+Git+Maven+MySQL+Idea)之一步到位
说明 所谓万事开头难,对于初学Java和Springboot框架的小伙伴往往会花不少时间在开发环境搭建上面.究其原因其实还是不熟悉,作为在IT界摸爬滚打数年的老司机,对于各种开发环境搭建已经了然于胸, ...