Excel开发中与线程相关的几个问题

采用VSTO或者Shared Add-in等技术开发Excel插件,其实是在与Excel提供的API在打交道,Excel本身的组件大多数都是COM组件,也就是说通过Excel PIA来与COM进行交互。这其中会存在一些问题,这些问题如果处理不好,通常会导致在运行的时候会抛出难以调试的COM异常,从而导致我们开发出的Excel插件的不稳定。

和普通的WinForm程序一样,Excel也是一种STA(Single Thread Apartment)线程的应用程序,Excel插件是寄宿在Excel中运行的,这也就意味着插件也是一种STA线程的应用程序。插件在操作Excel的时候,如果是在Excel的主线程中,可以直接获取Excel对象进行操作,比如写入单元格值,对单元格进行格式化等操作。但是通常,我们会在多线程或者后台工作线程中去处理一系列复杂的数据或者逻辑,待处理完成获得结果之后,再像WinForm那样,回到UI线程中,去更新界面信息,对于Excel插件来说,就是回到Excel的主线程上来,然后再更新界面。但是Excel又是一种不同于一般Winform 类型的STA,它是COM并且Excel插件是寄宿在其上的,所以还有一些需要注意的地方。

本文首先介绍什么是STA应用程序及其工作原理,然后介绍一般的Winform程序的界面刷新逻辑,以及在这其中非常重要的一个名为SynchronizationContext对象,最后介绍在Excel插件中如何获取Excel主线程,以及这其中需要注意的地方。

Excel插件的最难处理的地方在于其应用程序的稳定性,了解了Excel中的线程以及其机制对增强系统的稳定性会有很大的帮助。

1. STA(Single Thread Apartment)

COM组件的线程模型被称之为Apartment模型,即COM对象初始化时其执行上下文(Execution Context),他要么和单个线程关联STA(Single Thread Apartment ) 要么和多个线程关联MTA(Multi Thread Apartment)。

通常COM对象为了保护其自身维护的数据不被破坏,需要运行时来保证其不被多个线程同时调用;另外也需要运行时来保证对COM对象的调用不会阻塞UI线程。Apartment 就是COM对象生存的地方,一个Apartment可以包含一个或者多个线程。对一个COM对象的调用可以由该COM生存的Apartment中的任何一个线程接受和处理。如果一个Apartment中只有一个线程,那么就是STA线程,否则就是MTA,这个是在程序初始化COM组件的时候即确定下来的。一个进程可以包含多个STA,但是只有一个MTA。

STA模型是COM对象使用的一种非线程安全的模型,这意味着他不能处理自己的线程同步,通常在UI组件中使用这种模型。因此,如果其他线程需要和UI对象进行交互,需要将消息封送(marshall)到STA线程中。在Windows 窗体应用程序中,这一过程是通过窗口消息队列 (message pumping system)来实现的。当客户线程以STA 模式启动时,系统将为STA创建一个隐藏窗口类,所有的对COM对象的调用都会放到这个隐藏窗口的消息队列中。

如果COM对象能够处理其本身的同步逻辑,那么就是MTA模型了,他似的多个线程能够同时和对象进行交互,而不需要进行消息调用的封送。

COM组件在创建的时候采用哪种模型,可以在注册表项的ThreadingModel值中指定:

COM组件在注册表项中的ThreadingModel属性中会有一下四个属性:

Main thread. COM对象创建 在宿主程序的主UI线程上,所有的调用必须封送到 主UI线程上 .

Apartment. 表示该COM对象能够运行在任何但单线程模型的线程上,如果该线程是STA线程创建的,则对象运行在该STA线程上,否则该对象运行在主STA线程上,如果主STA线程不存在,系统则会自动创建一个。

Free. 表示该COM对象运行在MTA上。

Both. 表示该COM对象在那个模型上取决于创建Apartment的类型。

时间: 2024-12-22 12:37:17

Excel开发中与线程相关的几个问题的相关文章

Excel表格中视图功能相关详解

  Excel表格中视图功能相关详解          一.同时查看两个excel文件 打开两个excel文件 视图 - 全部重排 - 垂直/水平并排 二.同时查看同一个excel文件的两个excel工作表 视图 - 新建窗口 - 全部重排 - 垂直/水平并排 三.同时查看同一个表的两个不同区域 1.第一行不动(向下翻看excel表时,让一个表格的第一行固定不动) 视图 - 冻结窗格 - 冻结首行 2.同时查看两个动态区域 选取某一行 - 视图 - 拆分,可以把界面拆分成上下两部分,和冻结不同的

win8 app store开发中在线程或定时器中访问页面的控件

问题描述 win8appstore开发中在线程或定时器中访问页面的控件,请问怎样实现 解决方案 解决方案二:Dispatcher.runasync解决方案三:参考

浅谈Excel开发(九) Excel开发中遇到的常见问题及解决方法

相关文章: 浅谈Excel开发(1) Excel开发概述 浅谈Excel开发(二) Excel 菜单系统 浅谈Excel开发(三) Excel 对象模型 Excel开发过程中有时候会遇到各种奇怪的问题,下面就列出一些本人在开发中遇到的一些比较典型的问题,并给出了解决方法,希望对大家有所帮助. 一 插件调试不了以及错误导致崩溃的问题 在开发机器上,有时可能会装有多个版本的.NET运行时,有时候也可能装有多个版本的Visual Studio,本人的开发机器上就安装了3个版本的Visual Studi

Java开发中的线程安全选择与Swing

Swing API的设计目标是强大.灵活和易用.特别地,我们希望能让程序员们方便地建立新的Swing组件,不论是从头开始还是通过扩展我们所提供的一些组件. 出于这个目的,我们不要求Swing组件支持多线程访问.相反,我们向组件发送请求并在单一线程中执行请求. 本文讨论线程和Swing组件.目的不仅是为了帮助你以线程安全的方式使用Swing API,而且解释了我们为什么会选择现在这样的线程方案. 本文包括以下内容: ◆单线程规则:Swing线程在同一时刻仅能被一个线程所访问.一般来说,这个线程是事

Java开发中的线程安全选择与Swing[Z]

安全 Swing API的设计目标是强大.灵活和易用.特别地,我们希望能让程序员们方便地建立新的Swing组件,不论是从头开始还是通过扩展我们所提供的一些组件. 出于这个目的,我们不要求Swing组件支持多线程访问.相反,我们向组件发送请求并在单一线程中执行请求. 本文讨论线程和Swing组件.目的不仅是为了帮助你以线程安全的方式使用Swing API,而且解释了我们为什么会选择现在这样的线程方案. 本文包括以下内容: 单线程规则:Swing线程在同一时刻仅能被一个线程所访问.一般来说,这个线程

详解iOS开发中Keychain的相关使用_IOS

一.Keychain 基础 根据苹果的介绍,iOS设备中的Keychain是一个安全的存储容器,可以用来为不同应用保存敏感信息比如用户名,密码,网络密码,认证令牌.苹果自己用keychain来保存Wi-Fi网络密码,VPN凭证等等.它是一个sqlite数据库,位于/private/var/Keychains/keychain-2.db,其保存的所有数据都是加密过的. 开发者通常会希望能够利用操作系统提供的功能来保存凭证(credentials)而不是把它们(凭证)保存到NSUserDefault

PHP 开发中数据库及其相关软件的选型考虑

PHP 版本各异,已经停止升级开发的有 4.0 系列的 4.4.x,但现在还有部分生产环境在跑这个版本,需要继续维护代码.PHP 5.0 系列是现在开发和应用的主流版本,有 5.1.x 和 5.2.x 系列.PHP 6.0 目前还是试用版本,用 PHP 开发软件产品的人现在可以预先作兼容性测试. PHP 支持的数据库很多,包括 PHP 本身自带的数据库驱动组件,例如 mysql.dll.oci_oracle 等.PHP 从 5.1 版本以后正在力推其通用的数据库驱动组件 PDO,通过这个高度抽象

Android开发中编写蓝牙相关功能的核心代码讲解_Android

一. 什么是蓝牙(Bluetooth)?1.1  BuleTooth是目前使用最广泛的无线通信协议 1.2  主要针对短距离设备通讯(10m) 1.3  常用于连接耳机,鼠标和移动通讯设备等.二. 与蓝牙相关的API2.1 BluetoothAdapter: 代表了本地的蓝牙适配器 2.2 BluetoothDevice 代表了一个远程的Bluetooth设备三. 扫描已经配对的蓝牙设备(1)注:必须部署在真实手机上,模拟器无法实现 首先需要在AndroidManifest.xml 声明蓝牙权限

Android开发中编写蓝牙相关功能的核心代码讲解

一. 什么是蓝牙(Bluetooth)? 1.1  BuleTooth是目前使用最广泛的无线通信协议 1.2  主要针对短距离设备通讯(10m) 1.3  常用于连接耳机,鼠标和移动通讯设备等. 二. 与蓝牙相关的API 2.1 BluetoothAdapter: 代表了本地的蓝牙适配器 2.2 BluetoothDevice 代表了一个远程的Bluetooth设备 三. 扫描已经配对的蓝牙设备(1) 注:必须部署在真实手机上,模拟器无法实现 首先需要在AndroidManifest.xml 声