|Important||This document may not represent best practices for current development, links to downloads and other resources may no longer be valid. Current recommended version can be found here.|
Threading Support in Office
This topic provides information about how threading is supported in the Microsoft Office 2003 object model. The Office object model is not thread safe, but it is possible to work with multiple threads in an Office solution. Office applications are Component Object Model (COM) servers. COM allows clients to call COM servers on arbitrary threads. For COM servers that are not thread safe, COM provides a mechanism to serialize concurrent calls so that only one logical thread executes on the server at any time. This mechanism is known as the single-threaded apartment (STA) model. Because calls are serialized, callers might be blocked for periods of time while the server is busy or is handling other calls on a background thread.
Knowledge Required When Using Multiple Threads
To work with multiple threads, you must have at least basic knowledge of the following aspects of multithreading:
COM multithreaded concepts
For general information on multithreading, see.
Office runs in the main STA. Understanding the implications of this makes it possible to understand how to use multiple threads with Office.
Basic Multithreading Scenario
Microsoft Visual Studio 2005 Tools for the Microsoft Office System code always runs on the main UI thread. You might want to smooth out application performance by running a separate task on a background thread. The goal is to complete two tasks seemingly at once instead of one task followed by the other, which should result in smoother execution (the main reason to use multiple threads). For example, you might have your event code on the main Excel UI thread, and on a background thread you might run a task that gathers data from a server and updates cells in the Excel UI with the data from the server.
Background Threads That Call into the Office Object Model
When a background thread makes a call to the Office application (Word or Excel), the call is automatically marshaled across the STA boundary. However, there is no guarantee that Excel can handle the call at the time the background thread makes it. There are several possibilities:
Excel must pump messages for the call to have the opportunity to enter. If it is doing heavy processing without yielding this could take time.
If another logical thread is already in the apartment, the new thread cannot enter. This often happens when a logical thread enters Excel and then makes a reentrant call back to the caller's apartment. Excel is blocked waiting for that call to return.
Excel might be in a state such that it cannot immediately handle an incoming call. For example, Excel might be displaying a modal dialog.
For possibilities 2 and 3, COM provides an interface called IMessageFilter. If the server implements it, all calls enter through a method called HandleIncomingCall. For possiblity 2, calls are automatically rejected. For possibility 3, the server can reject the call, depending on the circumstances. If the call is rejected, the caller must decide what to do. Normally, the caller implements IMessageFilter, in which case it would be notified of the rejection by the RetryRejectedCall method.
However, in the Visual Studio Tools for Office case, COM interop converts all rejected calls to a("The message filter indicated that the application is busy"). Whenever you make an object model call on a background thread, you must to be prepared to handle this exception. Typically, that involves retrying for a certain amount of time and then displaying a dialog. However, you can also create the background thread as STA and then register a message filter for that thread to handle this case.
Starting the Thread Correctly
When you create a new STA thread, set the apartment state to STA before you start the thread:
System.Threading.Thread t = new System.Threading.Thread(AnObject.aMethod); t.SetApartmentState(System.Threading.ApartmentState.STA); t.Start();
For more information, see.
A modeless form allows some type of interaction with the application while the form is displayed. The user interacts with the form, and the form interacts with the application without closing. The Office object model supports managed modeless forms; however, it is not recommended to use them on a background thread.