Andrei Smolin

On using threads in managed Office extensions

Briefly: There are cases when using threads in your .NET-based Office add-in is okay; but in the general case, using threads isn’t recommended.

Consider a typical Outlook add-in scanning a lot of e-mails which should not prevent a user from working with the Outlook UI (the UI always runs in the main thread). An obvious solution is to move the scanning process to a thread. But…

Calling the Outlook object model in a thread is a wrong solution because the object model is almost not thread-safe. Almost? Well, yes, almost[i], but that means “always” for a developer!

Case studies:

a) An add-in using threads causes Outlook to hang or crash in a way that makes it look like another add-in is responsible[ii].

b) A while back, Add-in Express checked Inspectors.Count in a thread; this interfered with entering text in a message somehow.

Need to know more? Here are some extra details:

a) All calls to Office object models are executed in the main thread[iii], this is true even if you do such calls on a background thread.

A sample of such a call is nCount = theFolder.Items.Count. The described behavior is inherent to any Office object model because they all are STA[iv].

b) To transfer a COM call from a thread to the main thread, marshaling[v] is used.

What should normal people know about marshaling in managed Office extensions[vi]? It is sort of magic that your code invokes beside your knowledge. When or why this occurs seems to be inessential. What is essential is that it takes some time to marshal a COM call between threads[vii].

Conclusions:

a) A background thread in your add-in incurs some extra overhead, so if you run your business logics in the main thread, it works faster.

b) A background thread not using any Office object model is absolutely okay.

But how to scan Outlook items in the main thread in a way not interfering with the UI?

Add-in Express provides a solution: you use the SendMessage method and OnSendMessage event of your add-in module. This constitutes a kind of smart one-time timer. You call the method; and the event occurs only when Outlook is ready to process it. Find code samples via this search through Add-in Express forums.

Good luck!

Updated on 12-Oct-2011:
Here’s a citation from this MSDN blog: “There has been a rash of developers in recent months who are reporting problems with their Outlook add-ins crashing Outlook when doing multi-threading.”


[i] Geoff Darst from the VSTO Team talks on this in Is ApplicationClass Thread Safe?


[ii] See an article on OutlookCode.com, this is about non-managed add-ins, though


[iii] See All Outlook object model calls run on the main thread


[iv] If you really need it, see Single-Threaded Apartments (STA) on MSDN


[v] See What is Marshalling on Wikipedia


[vi] See Interop Marshaling on MSDN


[vii] See Marshaling Details on MSDN

One Comment

Post a comment

Have any questions? Ask us right now!