首页 > 其他分享 >UNO 已知问题 在后台线程触发 SKXamlCanvas 的 Invalidate 且在 PaintSurface 事件抛出异常将炸掉应用

UNO 已知问题 在后台线程触发 SKXamlCanvas 的 Invalidate 且在 PaintSurface 事件抛出异常将炸掉应用

时间:2024-09-12 20:03:45浏览次数:10  
标签:Invalidate git SKXamlCanvas PaintSurface 线程 异常

本文记录一个 UNO 已知问题,在 UNO 里面可以利用 SKXamlCanvas 对接 Skia 绘制到应用里面。如果此时在后台线程里面调用 SKXamlCanvas 的 Invalidate 触发界面的重新刷新,但在具体的执行绘制 PaintSurface 事件里面对外抛出异常,将会导致应用炸掉

背景: 我准备在 UNO 里面将 Microsoft.Maui.Graphics 对接进入,于是就用到了 SKXamlCanvas 控件。详细请看 https://github.com/unoplatform/uno/discussions/15097

当前行为: 当我使用 SKXamlCanvas 时,如果我在 PaintSurface 事件里面抛出任何异常,且当前的 PaintSurface 事件是由后台线程触发的,那将导致我的进程崩溃

预期行为:即使在 PaintSurface 事件里面抛出任何异常,应用程序也可以正常工作且收集到异常,比如通过 TaskScheduler.UnobservedTaskException 事件收集到异常

复现步骤:

  1. 添加 SKXamlCanvas 到 xaml 里
  2. 订阅 SKXamlCanvas 的 PaintSurface 事件,且在事件实现方法抛出异常
  3. 在后台线程调用 SKXamlCanvas 的 Invalidate 方法

核心的代码实现如下

在 XAML 添加 SKXamlCanvas 控件

  xmlns:sk="using:SkiaSharp.Views.Windows"

  <sk:SKXamlCanvas x:Name="Canvas" PaintSurface="OnPaintSurface" />

在后台代码里面使用后台线程调用 SKXamlCanvas 的 Invalidate 方法,且在 OnPaintSurface 抛出异常

            Task.Run(() =>
            {
                Canvas.Invalidate();
            });

        private void OnPaintSurface(object sender, SKPaintSurfaceEventArgs e)
        {
            throw new Exception();
        }

本文以上的复现代码放在githubgitee 欢迎访问

可以通过如下方式获取以上的复现代码,先创建一个空文件夹,接着使用命令行 cd 命令进入此空文件夹,在命令行里面输入以下代码,即可获取到本文的代码

git init
git remote add origin https://gitee.com/lindexi/lindexi_gd.git
git pull origin dde76effc23ebb9ee974b6ec276b242c39a50bdf

以上使用的是 gitee 的源,如果 gitee 不能访问,请替换为 github 的源。请在命令行继续输入以下代码

git remote remove origin
git remote add origin https://github.com/lindexi/lindexi_gd.git
git pull origin dde76effc23ebb9ee974b6ec276b242c39a50bdf

获取代码之后,进入 JagobawearjiNeewhiqakerki 文件夹

报告地址: https://github.com/unoplatform/uno/issues/15123

原因:

这是由于在 SkiaSharp 里面的错误实现导致踩到 dotnet 的另一个已知问题导致的。在 SKXamlCanvas 的具体实现里面,通过 async void 等待执行结果,而根据 dotnet 的已知问题可以知道,在 async void 收到任何异常都会导致进程崩溃,此行为详细请参阅 dotnet 警惕 async void 线程顶层异常

解决方法:

此问题已经被我修复,详细请看 Avoid async void in SKXamlCanvas. by lindexi · Pull Request #2720 · mono/SkiaSharp

标签:Invalidate,git,SKXamlCanvas,PaintSurface,线程,异常
From: https://www.cnblogs.com/lindexi/p/17975446

相关文章

  • VSTO:WinForms如何引用Ribbon.Invalidate
    问题描述:近期项目需要在VSTO插件中设计WinForms界面,该界面需要实现一个功能:当WinForms从外部应用中获取数据后,将其传递到editbox显示栏内。项目开发中遇到以下问题:WinForms中实例化Ribbon后,再引用其中的函数或Invalidate功能,在运行时会报错:System.NullReferenceException:“未将......
  • cache操作:clean、invalidate与flush的含义
    前言本文试图搞清楚cache几个操作:clean、invalidate与flush的含义。由于只用过ARM和RISC-V,所以是从ARM和RISC-V的角度来说明。 cachelinecacheline是cache的基本访问单元。cacheline一般都会包含valid和dirty两个状态位,如下图的v和d。valid位表示当前cacheline的内容是......
  • invalidate the cache in Spark by running 'REFRESH TABLE tableName' command in SQ
    ...1moreCausedby:java.io.FileNotFoundException:Filedoesnotexist:hdfs://ns1/user/hive/warehouse/dw.db/dw_uniswapv3_position_detail/pk_day=1689552000000/part-00000-bbe52b3b-4963-4c76-9ba9-e315305baed7.c000Itispossibletheunderlyingfileshave......
  • Oracle统计信息之NO_INVALIDATE参数
    文档课题:Oracle统计信息之NO_INVALIDATE参数.1、理论知识Oracle统计信息对于CBO至关重要.RBO建立在数据结构的基础上,DDL结构、约束会将SQL语句分为不同的成本结构等级.而CBO是在数据结构的基础上加入数据表细粒度信息,将成本结构细化为成本cost值.相对于数据表的DDL结构,统计信息反......
  • GDI-InvalidateRect使客户区矩形区域的图形变得无效
     RECTrect;::GetClientRect(m_hWnd,&rect);//获取窗口客户区的坐标BOOLb=::InvalidateRect(m_hWnd,&rect,TRUE);//使客户区矩形区域的图形变得无效/*使原来画的图像无效参数1:HWNDhWnd窗口句柄如果为NULL,则系统将在函数返......
  • 项目一众筹网02_2_管理员登录(转发改成重定向到主页面、退出登录(转发和重定向的区别、
    系列文章目录文章目录​​系列文章目录​​​​12-管理员登录-重定向到主页面​​​​13-管理员登录-退出登录​​​​14-管理员登录-抽取后台主页面​​​​新建jsp模板​......
  • C# get form to invalidate when form is resized?
    我刚刚接受了一个挑战,创建一个64个相同矩形或正方形的颜色交替的棋盘,从技术上来说,我已经完成了这个挑战;但是出于好奇,我注意到当用户调整窗体的大小并拖动它时,窗体会一直重......
  • idea每次启动后,均要执行Invalidate Caches操作,否则会有部分引入的依赖飘红;
    背景:随着项目代码量的增加,某日启动idea后,部分引入的依赖漂红;每一次启动idea后,均要执行清除缓存才能使用;file-->InvalidateCaches…解决方案:help-->EditCus......
  • 有关Idea的Invalidate Caches/Restart (Idea本地缓存异常,导致Idea无法识别Maven依赖)
    分析原因:有时我们自己在编写项目后,再次打开会发现自己封装的类,导入后还是爆红。这是因为Idea本地缓存异常,导致Idea无法识别Maven依赖,从而无法找到某些类。解决方式:通过Idea......