【ArcGIS Pro二次开发】(31):ArcGIS Pro中的多线程

article/2025/10/15 20:17:06

ArcGIS Pro与旧的ArcGIS桌面应用程序的显著不同之处在于,它采用多线程架构,可以有效的发挥多核CPU的优势。这使得二次开发工具的性能变得更好,但也对开发工作带来了更多的难点和挑战。


一、多线程需要注意的问题

  • 一般情况下,为了确保响应式用户体验,图形用户界面(GUI)线程必须能够从用户那里获取输入,并流畅地输出。这意味着GUI线程和你主要的工作线程必须在不同的线程上异步执行,GUI线程不应执行其他工作,二者不能互相干扰。
  • 在后台线程上执行工作时,必须向用户显示逻辑一致且信息丰富的用户界面。应根据正在后台执行的操作,提供必要的对用户界面的操作指令,以及适当的反馈。如果长时间运行的后台操作在逻辑上可以取消,则应提供取消选项。
  • 如果操作之间存在冲突,不应同时执行,而应按适当的逻辑顺序执行。例如,当包含地图的工程仍在加载过程中时,就不能对地图执行操作。通过用户交互启动的大多数操作在逻辑上依赖于顺序,应串行执行。
  • 在异步执行时要注意多个线程同时对同一个变量、文件、要素的访问,或者错误的访问顺序,比如说,复制一个要素,再删除原要素,如果顺序反过来了,先删除就没办法复制了。这个问题在单线程中几乎不存在,因为顺序是一目了然的。但是线程一旦变多,逻辑复杂的情况下,难免会有错漏。

二、ArcGIS Pro内部线程模型

当然,我们在ArcGIS Pro二次开发中也不用那么深入学习。因为ArcGIS Pro SDK的基础架构已经降低了代码的复杂性。

在大多数情况下,我们只需处理两个线程:【用户界面线程】和应用程序提供的单个【专用工作线程】。在内部,ArcGIS Pro使用大量线程来实现栅格化、图形渲染、数据加载以及利用并行性来加速计算的选择地理处理算法。但是这些线程完全是内部线程,和我们外部的开发没有关系。

当我们调用公共API中的方法时,可能会拆分为多个内部方法去实现,并将片段委托给一个或多个的专用内部线程。


三、Task和Task异步模式

ArcGIS Pro SDK 中的方法分为三类:

1、可在任何线程上调用的异步方法。这种类型的方法会加1个【async】修饰词,通常是返回任务。但是如果返回的是变量,则需要异步调用。

2、仅在工作线程上调用的同步方法。

3、仅在GUI线程上调用的同步方法。这些类型的方法通常与WPF相关联。

.NET引入了最重要的【async】和【await】语言功能。

【async】修饰符用于标记该方法,以便编译器知道该方法是异步的。

【await】则用于异步调用方法,然后强制调用线程自动返回到下一行并在异步操作完成后继续执行。

  private async void Button_Click(object sender, RoutedEventArgs e){double computedValue = await Task.Run<double>(()=>{double result = 42.0;        return result;});// 在上面await后的内容执行完毕后,才会执行下面的MessageBox任务MessageBox.Show(String.Format("Result was {0}",  computedValue.ToString()));}

以上面的代码为例,await后的异步方法执行完后,才会继续MessageBox.Show()方法。

输出结果为【Result was 42】


四、QueuedTask的使用

虽然Task可以在任意的Add-in代码中运行,但ArcGIS Pro SDK框架提供了一个更优秀的QueuedTask,实际上在开发中,我们基本就只使用到这个QueuedTask。

这是一个自定义的任务调度程序,通过使用【QueuedTask.Run】用来调度ArcGIS Pro SDK中的同步方法的任务。这种调度本质是一个排队方法,可以让多个任务有序执行。

示例代码如下:

  Task t = QueuedTask.Run(()=>{// 在此处调用同步SDK方法});

相较于Task类,在ArcGIS Pro SDK中使用QueuedTask类有很多优势。

1、在任务主体中,开发人员可以访问ArcGIS Pro的各种对象,例如地图、图层、要素等。这些对象的访问是线程安全的,因为QueuedTask会自动管理与主线程之间的通信。

2、如果任务需要更新UI元素,例如修改地图视图或显示进度信息,开发人员可以使用QueuedTask的Dispatcher属性,将更新操作包装在Dispatcher.BeginInvoke方法中。这样可以确保更新操作在主线程上执行,避免线程冲突。

3、如果需要取消任务,开发人员可以调用QueuedTask.Cancel方法,该方法将触发任务的取消操作。被取消的任务会在取消后尽快退出,并且可以在任务主体中进行必要的清理工作。

4、如果任务执行过程中发生异常,QueuedTask会捕获异常并将其传递给开发人员,以便进行适当的处理。开发人员可以在任务主体中使用try-catch块来捕获并处理异常。

总之,ArcGIS Pro SDK中的QueuedTask提供了一种方便而强大的机制,用于在后台执行任务并安全地与ArcGIS Pro应用程序的UI线程进行交互。它的优点包括多线程支持、UI线程安全、可取消和异常处理等。通过合理地使用QueuedTask,开发人员可以实现高效、可靠的自定义功能和扩展。

QueuedTask任务的执行顺序

这里举2个例子来说明一下QueuedTask任务的执行顺序。

            MessageBox.Show("1");await QueuedTask.Run(() =>{MessageBox.Show("2");MessageBox.Show("3");});MessageBox.Show("4");

以上面的代码为例,这是一个正常的、合理的异步执行。MessageBox的显示顺序为【1、2、3、4】。

但是如果将await的内容写成方法,并同步调用,情况则不同:

        MessageBox.Show("1");Spa();MessageBox.Show("4");public static async void Spa(){await QueuedTask.Run(() =>{MessageBox.Show("spa_1");MessageBox.Show("spa_2");});}

执行上面的代码,MessageBox的显示顺序为【1、(spa_1、spa_2)、4】。变成了并行执行,很明显,这种执行方式顺序混乱,很容易造成错误。

不幸的是,至目前为止,我已经犯了很多这样的错。

因为个人习惯将一些通用的流程写成方法并调用,造成写了很多异步的方法,在调用的时候又直接同步调用。出了不少的BUG,调来调去才发现是异步并行的原因。

在上面代码的基础上进行修改,主代码中将自定义的方法改为异步执行,方法内部改为同步执行:

        MessageBox.Show("1");await QueuedTask.Run(() =>{Spa();});MessageBox.Show("4");public static async void Spa(){MessageBox.Show("spa_1");MessageBox.Show("spa_2");}

运行结果,流程变回了串行执行,勉强解决了并行的问题。

基础太弱果然还是不行,这也是现在回头补基础,并记录这篇文章的主要原因。


http://chatgpt.dhexx.cn/article/80g32kvT.shtml

相关文章

GIS二次开发:实验一 ArcGIS Engine 开发初步

实验一 ArcGIS Engine 开发初步 一、实验目的 掌握ArcGIS Engine的安装&#xff1b;熟悉ArcGIS Engine中几个常用的控件&#xff1b;搭建第一个简单的ArcGIS Engine 程序&#xff1b;通过ICommand接口添加地图浏览工具。 二、实验仪器与设备 计算机、visual studio 软件、A…

Arcgis二次开发软件安装(Arcgis10.2、VS2012、AE10.2)

目录 一、序言 二、Arcgis10.2安装 &#xff08;一&#xff09;安装ArcGIS License Manager 1.1 ArcGIS License Manager安装 1.2 ArcGIS License Manager配置 &#xff08;二&#xff09;安装ArcGIS Desktop 1.1ArcGIS Desktop安装 1.2.ArcGIS文件替换 1.3中文显示与…

StackPanel 实现从上往下+从右往左 排列+RenderTransform特效实例分析

StackPanel:将子元素排列到可沿水平或垂直放置的行。 参考资料&#xff1a; 1. StackPanel类 2. Silverlight学习笔记&#xff08;九&#xff09;——RenderTransform特效【五种基本变换】及【矩阵变换MatrixTransform】 3. MatrixTransform矩阵变换 stack表明StackPane…

控件篇 - 子控件在StackPanel里的居中问题

如下面代码&#xff1a; <StackPanel Width"200" Height"80" Background"Tomato"><TextBlock HorizontalAlignment"Center" VerticalAlignment"Center" Text"ABCD"/></StackPanel> 原意是想通…

Docker Stack

大规模场景下的多服务部署和管理是一件很难的事情。Docker Stack 为解决该问题而生&#xff0c;Docker Stack 通过提供期望状态、滚动升级、简单易用、扩缩容、健康检查等特性简化了应用的管理&#xff0c;这些功能都封装在一个完美的声明式模型当中。 Stack 能够在单个声明文…

StackPanel布局

StackPanel可以把内部元素在纵向或横向上紧凑排列&#xff0c;形成栈式布局。 示例代码&#xff1a; <Grid><GroupBox Header"请选择没有错别字的成语" BorderBrush"Black" Margin"5"><StackPanel Margin"5" Heig…

2.12 Stack

2.12 Stack Stack也是List接口的实现类之一&#xff0c;和Vector一样&#xff0c;因为性能原因&#xff0c;更主要在开发过程中很少用到栈这种数据结构&#xff0c;不过栈在计算机底层是一种非常重要的数据结构&#xff0c;下边将探讨下Java中Stack。 2.12.1 Stack的继承关系 …

wpf之StackPanel布局

注意两个参数&#xff1a; Orientation &#xff1a;控制排列是水平方向&#xff0c;还是垂直方向&#xff08;Horizontal 水平方向 Vertical垂直方向&#xff09; FlowDirection&#xff1a;控制控件排序是从右往左还是从左往右&#xff0c;写两个简单的demo如下&#xff…

四、StackPanel控件

StackPanel可以把内部控件在纵向或横向上紧凑排列、形成栈式布局&#xff0c;当上层控件不被删除时&#xff0c;剩余的控件会前移&#xff0c;填充空白 特点&#xff1a; 同类控件紧凑排列移除其中…

WPF 控制StackPanel用法

StackPanel是非常相似的WrapPanel&#xff0c;但至少有一个重要的区别&#xff1a;StackPanel的不换行的内容。相反&#xff0c;它将内容向一个方向拉伸&#xff0c;允许您将一项一项一项地堆叠在一起。让我们首先尝试一个非常简单的示例&#xff0c;就像我们对 WrapPanel 所做…

2021-08-16 WPF控件专题 StackPanel 控件详解

1.StackPanel 控件介绍 堆栈面板 —布局控件 —Panel 子元素排列成一行或一列 水平 垂直 FlowDirection 子元素的流动方向 Orientation&#xff1a;Horizontal 一行 一般设置VerticalAlignment&#xff1a;Top Bottom Center Stretch Vertical 一列 HorizontalAlignment Left…

WPF中StackPanel的尺寸的怪癖

前几天写了文章&#xff1a;WPF中的DataGrid控件的VerticalScrollBarVisibility属性失效 今天继续补充StackPanel的特点&#xff0c;可以作为对上述文章的进一步解释。 在WPF中&#xff0c;StackPanel是十分常用的布局元素。然而&#xff0c;该元素和很多其它元素不同&#x…

StackPanel

原文链接&#xff1a;http://www.cnblogs.com/Jennifer/articles/1987757.html Canvas、StackPanel、WrapPanel、DockPanel和Grid是WPF中主要的5种内建面板&#xff0c;这些面板类都位于System.Windows.Controls命名空间下。 StackPanel是一个受欢迎的面板&#xff0c;因为它方…

WPF中的StackPanel、WrapPanel、DockPanel

一、StackPanel StackPanel是以堆叠的方式显示其中的控件 1、可以使用Orientation属性更改堆叠的顺序 Orientation"Vertical" 默认&#xff0c;由上到下显示各控件。控件在未定义的前提下&#xff0c;宽度为StackPanel的宽度&#xff0c;高度自动适应控件中内容的高…

WPF布局控件之StackPanel

StackPanel Stack&#xff0c;英文意思是堆栈&#xff0c;StackPanel&#xff0c;意思是堆栈式布局&#xff0c;相当于把控件给堆起来。如果不设置StackPanel中控件的宽高&#xff0c;那么其中控件的宽高是默认和StackPanel一样的&#xff0c;如果设置控件宽高&#xff0c;那么…

WPF-StackPanel面板

StackPanel Orientation属性 Orientation属性决定SatckPanel中元素的排列方向&#xff0c;默认为垂直排列 Orientation“Vertical” <Window x:Class"StackPanel.MainWindow"xmlns"http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:…

WPF之路——StackPanel布局(堆栈面板)

StackPanel是一个受欢迎的面板&#xff0c;因为它方便好用&#xff0c;它会顺序对它的子元素进行排列。它是少数几个没有定义任何附加属性的面板之一。由于没有附加属性来排列子元素&#xff0c;只有一种方法可以定制StackPanel的行为——设置Orientation属性为Horizontal或Ver…

解决StackPanel滚动条无法显示

解决StackPanel滚动条无法显示 解决方法 1.添加容器:xtraScrollableControl 2.StackPanel隐藏属性 StackPanel.AutoScroll true (设计界面StackPanel控件无法找到该属性&#xff0c;代码设置) 配个显示效果图

ITS堆栈

ITS堆栈 1. ITS堆栈 - 参考体系结构2. C-V2X 重用汽车行业定义的上层3. C-V2X – DSRC 协议栈比较4. V2X 堆栈的演变&#xff08;欧盟版&#xff09;5. 802.11 和 IEEE 1609.X 规范6. 常见的 ITS 消息7. SAE International J2735 消息&#xff1a;示例8. ETSI CAM/DENM 消息&am…

布局之WrapPanel与StackPanel

布局之WrapPanel与StackPanel 一、WrapPanel WrapPanel布局面板将各个控件从左至右按照行或列的顺序罗列&#xff0c;当长度或高度不够是就会自动调整进行换行&#xff0c;后续排序按照从上至下或从右至左的顺序进行。 Orientation——根据内容自动换行。当Horizontal选项看…