在 MAUI 里,可以使用 PathFigureCollectionConverter 将 Path 字符串转换为 PathFigureCollection 对象,从而实现从 Path 字符串转换为路径几何。然而这个 PathFigureCollectionConverter 转换器非线程安全,即使创建多个实例对象,依然由于内部的静态字段导致非线程安全,本文将记录此问题的原理

当前,此 PathFigureCollectionConverter 非线程安全问题,没有规避方法

我将此问题报告给官方,请看 https://github.com/dotnet/maui/issues/11321

然后官方说,你也是 Member 了,是一个成熟的开发者了,自己发现的问题就要自己修。于是我乖乖修了这个问题,请看 https://github.com/dotnet/maui/pull/11497 修了之后发现性能居然还提升了一点

复现步骤:

只需要让 PathFigureCollectionConverter 进入多线程转换 Path 字符串即可,转换过程,将随机抛出异常

最简代码如下

        var pathFigureCollectionConverter = new PathFigureCollectionConverter();
var pathString1 =
"M320 96a64 64 0 0 0-64 64V896a64 64 0 0 0 64 64h384a64 64 0 0 0 64-64V160a64 64 0 0 0-64-64H320z m384 64V896H320V160h384zM128 256v576h64V256H128zM832 256v576h64V256h-64z";
var pathString2 =
"M230.08 738.56l58.816 58.88L574.336 512l-285.44-285.44-58.88 58.88L456.704 512l-226.56 226.56z m487.04 29.44V256h-83.2v512h83.2z"; _ = pathFigureCollectionConverter.ConvertFrom(pathString1);
_ = pathFigureCollectionConverter.ConvertFrom(pathString2); for (int i = 0; i < 100; i++)
{
Task.Run(() =>
{
var pathFigureCollection = pathFigureCollectionConverter.ConvertFrom(pathString1);
});
} for (int i = 0; i < 100; i++)
{
Task.Run(() =>
{
var pathFigureCollection = pathFigureCollectionConverter.ConvertFrom(pathString2);
});
}

包含此代码的项目放在 GitHub 上,请看 https://github.com/lindexi/lindexi_gd/tree/abc3042ddbfc3bd46563119fc88df0463b155c8b/TestPathFigureCollectionConverter

导致 PathFigureCollectionConverter 非线程安全的核心原因是采用静态字段记录状态,以下是 PathFigureCollectionConverter 的部分源代码,代码有删减

        static bool _figureStarted;
static string _pathString;
static int _pathLength;
static int _curIndex;
static Point _lastStart;
static Point _lastPoint;
static Point _secondLastPoint;
static char _token; static void ParseToPathFigureCollection(PathFigureCollection pathFigureCollection, string pathString, int startIndex)
{
PathFigure pathFigure = null; _pathString = pathString;
_pathLength = pathString.Length;
_curIndex = startIndex; // 忽略其他代码
}

完全的代码请看 https://github.com/dotnet/maui/blob/a541df0816d1867f494186a0bdc214d431e000cd/src/Controls/src/Core/Shapes/PathFigureCollectionConverter.cs

从上面代码可以看到,用到了静态字段。这是非多线程安全的,多个线程将会随机更改污染静态字段,从而让转换逻辑无法成功执行

MAUI 已知问题 PathFigureCollectionConverter 非线程安全的更多相关文章

  1. java面试题:已知一个数组[2,4,6,2,1,5],将该数组进行排序(降序,不能用工具类进行排序),创建两条线程交替输出排序后的数组,线程名自定义

    package com.swift; import java.util.Arrays; import java.util.Comparator; public class ArrayThread_Te ...

  2. 如何利用AI识别未知——加入未知类(不太靠谱),检测待识别数据和已知样本数据的匹配程度(例如使用CNN降维,再用knn类似距离来实现),将问题转化为特征搜索问题而非决策问题,使用HTM算法(记忆+模式匹配预测就是智能),GAN异常检测,RBF

    https://www.researchgate.net/post/How_to_determine_unknown_class_using_neural_network 里面有讨论,说是用rbf神经 ...

  3. 对象布局已知时 C++ 对象指针的转换时地址调整

    在我调试和研究 netscape 系浏览器插件开发时,注意到了这个问题.即,在对象布局已知(即对象之间具有继承关系)时,不同类型对象的指针进行转换(不管是隐式的从下向上转换,还是强制的从上到下转换)时 ...

  4. 剑指offer——已知二叉树的先序和中序排列,重构二叉树

    这是剑指offer中关于二叉树重构的一道题.题目原型为: 输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树.假设输入的前序遍历和中序遍历的结果中都不含重复的数字.例如输入前序遍历序列{1,2, ...

  5. WP8.1开发者预览版本号已知 Bug

    偶的 Lumia 920 已经升级到最新的 8.1 开发者预览版本号,使用中没有发现什么问题. 可能是由于偶玩手机的情况比較少吧!忽然看到 MS 停止此版本号的更新,并说明有非常多的 BUG,偶就郁闷 ...

  6. [推荐]ORACLE PL/SQL编程之五:异常错误处理(知已知彼、百战不殆)

    原文:[推荐]ORACLE PL/SQL编程之五:异常错误处理(知已知彼.百战不殆) [推荐]ORACLE PL/SQL编程之五: 异常错误处理(知已知彼.百战不殆) 继上三篇:ORACLE PL/S ...

  7. 实战分享:如何成功防护1.2T国内已知最大流量DDoS攻击

    作者:腾讯云宙斯盾安全团队&腾讯安全平台部 引言: DDoS攻击势头愈演愈烈,除了攻击手法的多样化发展之外,最直接的还是攻击流量的成倍增长.3月份国内的最大规模DDoS攻击纪录还停留在数百G规 ...

  8. 已知长度为n的线性表采用顺序结构,写一算法删除该线性表中所有值为item的元素

    /** * @author:(LiberHome) * @date:Created in 2019/2/27 23:34 * @description: * @version:$ */ /*已知长度为 ...

  9. TZOJ 3209 后序遍历(已知中序前序求后序)

    描述 在数据结构中,遍历是二叉树最重要的操作之一.所谓遍历(Traversal)是指沿着某条搜索路线,依次对树中每个结点均做一次且仅做一次访问. 这里给出三种遍历算法. 1.中序遍历的递归算法定义:  ...

  10. Xtts v4变化&先决条件&已知问题

    V4变化的主要有:     1.这个采购使用简化的命令.源的一个命令(--backup)和目标的一个命令(--restore). 2.此过程只需要在源和目标的$ TMPDIR(res.txt)之间复制 ...

随机推荐

  1. python高级技术(进程一)

    一 什么是进程 进程(Process)是计算机中的程序关于某数据集合上的一次运行活动,是系统进行资源分配和调度的基本单位,是操作系统结构的基础.在早期面向进程设计的计算机结构中,进程是程序的基本执行实 ...

  2. 三维模型OBJ格式轻量化压缩在大规模场景的加载和渲染的作用分析

    三维模型OBJ格式轻量化压缩在大规模场景的加载和渲染的作用分析 OBJ格式是一种常用的三维模型文件格式,它存储了三维模型的几何信息和纹理坐标等相关属性.在大规模场景中加载和渲染三维模型时,OBJ格式的 ...

  3. 记录--不定高度展开收起动画 css/js 实现

    这里给大家分享我在网上总结出来的一些知识,希望对大家有所帮助 不定高度展开收起动画 最近在做需求的时候,遇见了元素高度展开收起的动画需求,一开始是想到了使用 transition: all .3s; ...

  4. mysql数据库锁MDL锁的解释

    1.背景 在我们系统中有一张表它的查询概率非常高.最近有个需求,需要对这个表增加一个字段,然而在增加字段的时候发现系统中有多个业务出现了超时操作,那么这个是什么原因导致的呢?经过查阅资料发现是数据库的 ...

  5. 鸿蒙HarmonyOS实战-ArkUI组件(Swiper)

    一.Swiper 1.概述 Swiper可以实现手机.平板等移动端设备上的图片轮播效果,支持无缝轮播.自动播放.响应式布局等功能.Swiper轮播图具有使用简单.样式可定制.功能丰富.兼容性好等优点, ...

  6. 线段树(SegmentTree)

    对于数组应用于区间染色实现为On,而线段树是O(logn) 什么是线段树:对于一个二叉树,每一个节点存储的是一个线段或是一个区间相应的信息. 查询 更新 #pragma once #include & ...

  7. 'scanf': This function or variable may be unsafe

    'scanf': This function or variable may be unsafe. Consider using scanf_s instead. To disable depreca ...

  8. Jenkins设置定时触发器执行任务

    1. 选中任务,选择配置/构建触发器,选择定时构建 2. 填写定时器参数,格式说明如下,共五个参数,参数之间空格隔开,不需要填的直接*号即可.  此处d定时任务的格式遵循 cron 的语法(可以与 c ...

  9. 掌握 C++ 编译过程:面试中常见问题解析

    C++是一种高级编程语言,但是计算机并不能直接理解它.因此,需要将C++代码翻译成计算机可以理解的机器语言.这个过程就是编译过程,是C++程序从源代码到可执行文件的转换过程,包括预处理.编译.汇编和链 ...

  10. 华为3D建模服务(3D Modeling Kit),轻松构建高质量3D模型

    华为3D建模服务(3D Modeling Kit)是华为在图形图像领域又一技术开放,面向有3D模型.动画制作等能力诉求的应用开发者,基于AI技术,提供3D物体模型自动生成和PBR材质生成功能,实现3D ...