WinAppSDK / WinUI3 项目无法使用 SystemEvents 的问题

这篇具有很好参考价值的文章主要介绍了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 内部线程上触发事件,自然就能正常触发了。文章来源地址https://www.toymoban.com/news/detail-842728.html

到了这里,关于WinAppSDK / WinUI3 项目无法使用 SystemEvents 的问题的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • WinUI(WASDK)使用HelixToolkit加载机器人3D模型并进行项目实践

    本人之前开发了一个叫电子脑壳的上位机应用,给稚晖君ElectronBot开源机器人提供一些功能,但是由于是结合硬件才能使用的软件,如果拥有硬件的人员太少,就会导致我的软件没什么人用,于是我就想着能不能将机器人硬件的模型加载到软件里,这样用户就可以不使用硬件

    2024年02月08日
    浏览(119)
  • 解决引入spire.doc.free-3.9.0.jar导致spring boot项目无法使用maven的install问题

    问题背景: 在一个项目中需求中需要导出一个word模板,那之前有做过一个这个类似需求,这次使用的是freemarker模版。在引入spire.doc.free-3.9.0.jar依赖的时候发现maven依赖报红色,悬浮提示aliyun找不到改包,没有太在意这个部分,本地能够正常使用。本地仓库存在这个jar包,并

    2024年02月15日
    浏览(50)
  • WinUI(WASDK)使用MediaPipe检查人体姿态关键点

    之前有用这个MediaPipe.NET .NET包装库搞了手势识别,丰富了稚晖君的ElectronBot机器人的第三方上位机软件的功能,MediaPipe作为谷歌开源的机器视觉库,功能很丰富了,于是就开始整活了,来体验了一把人体姿态关键点检测。 这个框架是微软最新的应用开发框架,我是用来开发程

    2024年02月15日
    浏览(49)
  • 问题解决:idea克隆项目依赖无法解析

    问题描述 尝试解决方案 问题描述 从git远程仓库clone了一个springboot项目, 然后项目的pom.xml文件的依赖全部加载失败,全部是Project 某某某依赖 not found 的错误,几十条 代码就更不用看了,只要用到依赖,全部报错. 看着报错就头大 尝试解决方案 检查maven配置是否正确 检查是否对应你

    2024年02月16日
    浏览(43)
  • 【问题解决】Linux中无法下载Github的项目

    问题描述 就是连不上GitHub。 问题解决 解决方法一: (本人测试无效) 将连接地址的 https 改为 git 。 解决方法二: (本人测试有效) 第一步:打开 /etc/hosts 文件;命令: sudo vim /etc/hosts 第二步:添加下面的内容到文件末尾,保存退出即可。 成功解决 参考 linux下无法登陆

    2024年02月16日
    浏览(33)
  • Android Studio项目遇到的问题——无法找到目标设备

    Android Studio项目遇到的问题——无法找到目标设备 在进行Android应用程序开发的过程中,我们常常会遇到各种各样的问题。其中之一就是在进行真机测试时,Android Studio可能会显示\\\"No target device found\\\"的错误信息,意味着无法找到目标设备。本文将介绍此问题的解决方法,并提供

    2024年02月06日
    浏览(43)
  • 『pycharm 』解决无法添加解释器,无法新建项目问题(是无法添加解释器,不是没有添加解释器)

    这个问题和大家常见的: 没有Python解释器 这种简单问题不同。请看问题描述。👇👇 如图,解释器列表空空如也,即使点击“ 添加本地解释器 ”也没有反应(那个展开小三角也是空的)。 所有项目都这样了,那里变成空的了。而且这些都是我自己的项目,之前都好好的。 删

    2024年02月11日
    浏览(68)
  • vue项目预览pdf功能(解决动态文字无法显示的问题)

    最近,因为公司项目需要预览pdf的功能,开始的时候找了市面上的一些pdf插件,都能用,但是,后面因为pdf变成了需要根据内容进行变化的,然后,就出现了需要动态生成的文字不显示了。换了好多好多的插件,都无法显示,直接无语了。 (pdf-vue3,pdf.js,vue3-pdfjs, vue - pdf -

    2024年02月12日
    浏览(46)
  • Yarp项目代理ChatGPT,解决网络无法访问openAI的问题

    目的:通过代理解决网络无法访问openAI的问题 项目源码地址:https://github.com/raokun/YarpProject 创建一个webapi项目 PackageReference最新版本为2.0.0,复制PackageReference 项目中安装Yarp.ReverseProxy 配置内容: .net项目部署docker可参照我的博客:TerraMoursVue-V0.1部署(适用于通用的vue项目部署到

    2024年02月06日
    浏览(46)
  • VS2022无法打开Silverlight 项目的问题:改用VS2015

    警告: Microsoft Silverlight 已于 2021 年 10 月 12 日终止支持。 Silverlight 开发框架目前仅在 Internet Explorer 10 和 Internet Explorer 11 上受支持,对 Internet Explorer 10 的支持将于 2020 年 1 月 31 日结束。 不会再支持 Chrome、Firefox 或使用 Mac 操作系统的任何浏览器。 根据微软官方的解释: S

    2024年02月05日
    浏览(52)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包