在 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. Retrofit源码分析

    目录介绍 1.首先回顾Retrofit简单使用方法 2.Retrofit的创建流程源码分析 2.1 Retrofit对象调用Builder()源码解析 2.2 Retrofit对象调用baseUrl( ...

  2. 记录--纯CSS实现骚气红丝带

    这里给大家分享我在网上总结出来的一些知识,希望对大家有所帮助 在本文中,我们将探讨如何使用 CSS 以最少的代码创造出精美的 CSS 丝带形状,并最终实现下面这个效果: 下面我们使用html和css来 ...

  3. hdfs disk balancer 磁盘均衡器

    目录 1.背景 2.hdfs balancer和 hdfs disk balancer有何不同? 3.操作 3.1 生成计划 3.2 执行计划 3.3 查询计划 3.4 取消计划 4.和disk ba ...

  4. nginx location块

    location块在server块中使用,它的作用是根据客户端请求URL去定位不同的应用. 匹配格式 作用 location = /uri = 表示精确匹配,只有完全匹配上才能生效 location ...

  5. #数学期望,高斯消元#洛谷 3232 [HNOI2013]游走

    题目 分析 如果计算出边的期望经过次数那就可以算出来答案 首先转换成点的期望经过次数,设\(dp[x]\)表示点\(x\)的期望经过次数 那么\(dp[x]=\sum_{y\in son}\frac{ ...

  6. TVM 代码生成—TIR to LLVM IR

    本文地址:https://www.cnblogs.com/wanger-sjtu/p/17573212.html TVM在编译过程中,经历了 graph LR A[3rd IR] --> B[R ...

  7. MySQL 数据库查询与数据操作:使用 ORDER BY 排序和 DELETE 删除记录

    使用 ORDER BY 进行排序 使用 ORDER BY 语句按升序或降序对结果进行排序. ORDER BY 关键字默认按升序排序.要按降序排序结果,使用 DESC 关键字. 示例按名称按字母顺序排序 ...

  8. pip提示升级pip版本

    今天在进行pip安装库的时候发现下面出现一段黄色的字体,如下图: 自由翻译: 大概意思就是说我现在安装的pip的版本是 20.0.2,最新版本是 20.1,希望我可以更新到最新的版本,并告诉了我怎么安 ...

  9. Java程序员常用英语整理

    基础----进阶 A. array数组accessible 可存取的 area面积audio 音频 addition 加法 action 行动 arithmetic 算法adjustment 调整 a ...

  10. 打造HarmonyOS智能全场景,7大BUFF为您助力!

    <HarmonyOS Connect系列课>上线,7套课程教会开发者打造智能全场景: <HarmonyOS Connect系列课>共含7套课程,按照业务流程先后分别为--Dev ...