在 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. 详解SSL证书系列(5)SSL证书为什么不能好多年签一次呢

    上一篇介绍了详解SSL证书系列(4)免费的SSL证书和收费的证书有什么区别,这一篇我们继续了解一下我们申请的SSL证书为什么不能好多年签一次呢,这样不是更省事吗? SSL证书最多只能签发一年,一年到期 ...

  2. 记录--页面使用 scale 缩放实践

    这里给大家分享我在网上总结出来的一些知识,希望对大家有所帮助 最近接到一个任务,需要把页面放大1.5倍显示.这里使用 css 里的 transform: scale(1.5) 来实现. documen ...

  3. uni-app 地图全解析+事件监听

    最近找到了一篇uni-app的地图解决方案精品文章,这里分享给大家,希望对大家有所帮助 转载地址:https://blog.csdn.net/cplvfx/article/details/111447 ...

  4. KingbaseES 中的xmin,xmax等系统字段说明

    在KingbaseES中,当我们创建一个数据表时,数据库会隐式增加几个系统字段.这些字段由系统进行维护,用户一般不会感知它们的存在. 例如,以下语句创建了一个简单的表: create table te ...

  5. Luogu P3294 背单词

    观前须知 本题解全部内容遵循CC BY-NC-SA 4.0 Deed原则 更好的观看体验 点这里 笔者的博客主页 正文 Luogu P3294 [SCOI2016]背单词 笔者在刷题的时候看到了这道好 ...

  6. Android Graphics 多屏同显/异显 - C++示例程序(标准版)

    "为了理解Android多屏同显/异显的基本原理,我们将从Native Level入手,基于Graphics APIs写作一个简单的C++版本的多屏显示互动的演示程序.通过这个程序我们将了解 ...

  7. OpenHarmony应用ArkUI 状态管理开发范例

      本文转载自<#2023盲盒+码# OpenHarmony应用ArkUI 状态管理开发范例>,作者:zhushangyuan_ 本文根据橘子购物应用,实现ArkUI中的状态管理. 在声明 ...

  8. 三步就能在OpenHarmony中实现车牌识别

    介绍 本车牌识别项目是基于开源项目 EasyPR(Easy to do Plate Recognition)实现.EasyPR 是一个开源的中文车牌识别系统,基于 OpenCV 开源库开发. 本项目使 ...

  9. 轻松上手Jackjson(珍藏版)

    写在前面 虽然现在市面上有很多优秀的json解析库,但 Spring默认采用Jackson解析Json. 本文将通过一系列通俗易懂的代码示例,带你逐步掌握 Jackson 的基础用法.进阶技巧以及在实 ...

  10. 标签栏切换效果 JS

    标签栏切换效果 JS 要求:class为tab-box的元素用于实现标签栏的外边框,,分别实现标签栏的标签部分和内容部分. html <div class="tab-box" ...