首页 > 解决方案 > 如果后台线程不访问 Office 对象模型,是否需要在 MS Office 加载项中作为 STA 线程运行?

问题描述

我继承了 VSTO Outlook 加载项的一些代码。需要定期执行后台操作。该操作基本上是进行一些 Web 服务调用并将一些文件写入磁盘。它根本不访问 Outlook 对象模型。目前实现为一个连续运行的STA线程,通过循环和休眠来实现工作时间的计时,时间间隔为几分钟,不需要特别精确。

声称在后台线程上的所有处理都在 STA 线程上完成,否则 Outlook 崩溃并指出我这篇文章。我对这篇文章的解释是,只有当我调用 Outlook COM 模型时才需要一个 STA 线程,否则我看不到 Outlook 是如何知道另一个线程正在运行的。

在我看来,我最好使用System.Threading.Timer在线程池线程上运行工作而不是在Sleep. 我很想听听任何有在办公室插件中做这种事情的经验的人的意见。

标签: .netmultithreadingoutlookvstooffice-interop

解决方案


您不应该处理来自辅助线程的 Outlook 对象。当后台线程调用 Office 应用程序时,调用会自动跨 STA 边界封送。但是,不能保证 Office 应用程序可以在后台线程发出调用时处理调用。最新的 Outlook 版本可能会检测到此类跨线程调用并在运行时引发异常。

请注意,.NET 包含四个名为 的类Timer,每个类都提供不同的功能:

  • System.Timers.Timer:定期触发事件。该类旨在用作多线程环境中的基于服务器或服务组件;它没有用户界面,在运行时不可见。
  • System.Threading.Timer:定期在线程池线程上执行单个回调方法。回调方法是在定时器实例化时定义的,不能更改。与 System.Timers.Timer 类一样,此类旨在用作多线程环境中的基于服务器或服务组件;它没有用户界面,在运行时不可见。
  • System.Windows.Forms.Timer(仅限 .NET Framework):定期触发事件的 Windows 窗体组件。该组件没有用户界面,设计用于单线程环境。如果要在事件处理程序中访问 Outlook 对象,这是运行重复工作的推荐方法。
  • System.Web.UI.Timer(仅限 .NET Framework):一个 ASP.NET 组件,它定期执行异步或同步网页回发。

推荐阅读