4

我正在构建一个 VSTO 加载项:我需要运行一个后台线程,但该线程需要访问 COM 组件(我已实现 IMessageFilter 以使此消息传递尽可能安全)。我相信所有访问 OLE 或 COM 的线程都必须是 STA;因此,BackgroundWorker 不在讨论范围内。

我很高兴使用普通线程并将 ApartmentState 设置为 STA,但我还需要知道该线程何时完成,以便更新一些 UI 内容。我不想 Join() 因为它会锁定 UI(这是我使用线程的全部原因!)。

在我的线程方法结束时触发某种事件并让该事件完成我需要的完成的事情的最佳实践是什么?

或者

投票比较好

   while(!_threadFinishedStarting)
   {
        Application.DoEvents();
        Thread.Sleep(100);
   }

如此处所述:C#.net - 如何提醒程序线程已完成(事件驱动)?

非常感谢

4

1 回答 1

3

您可以在启动线程之前调用 Thread.SetApartmentState() 来选择一个 STA。您还必须抽取消息循环,这是 STA 线程的要求。这往往很困难并且经常被跳过,如果您的代码死锁或您的 IMessageFilter 抱怨,您知道您需要一个。

请注意另一个要求,STA 仅在您还创建要在同一线程上使用的对象时才有效。这往往是 VSTO 加载项中的问题,您通常希望使用 Office 对象模型提供的对象。您无法选择创建该对象的位置。

如果这完全正确,那么您就无法创建自己的 STA 线程,因为无论如何调用都会被编组。在这种情况下,BGW 就可以了,因为无论如何您都无法取得进展,因此在这两种情况下,呼叫都会被编组。线程安全没有免费的午餐。

于 2013-07-28T21:56:41.570 回答