calo_

Hi,

I have a c# applcation that creates an excel application object, open a workbook and read/write data from/to an an active sheet. All works fine as long as I use the same thread for all accesses to the excel application object.

Now, in my application, I acquired data in real time and store them inside two buffers that I use in a ping-pong manner. Once a buffer is full, I raise an event that inform the subscriber that data must be transfered to the excel file while the other buffer is filled with new incomming data. I raise this event on a secondary thread and I would like that this thread does the writting in the exel file whereas the other thread (i.e. the thread that creates the excel application object) performs other tasks in my application.

When the secondary thread access any properties or methods of the excel application object, the thread blocks and nothing appens. After one minute I receive a message:

" ContextSwitchDeadlock was detected
Message: The CLR has been unable to transition from COM context 0x1a06c0 to COM context 0x1a0608 for 60 seconds. The thread that owns ..."

Is it because COM objects can only be accessed by the thread that has created them Is there a way of writting these data inside excel form a secondary thread that has not created the excel application object.

Thank you for your help




Re: Visual Studio Tools for Office Access microsoft excel from different thread.

Dennis Wallentin

Hi calo_

Take a look in the following thread, especially the answer from Geoff Darst: Excel process hanging issue






Re: Visual Studio Tools for Office Access microsoft excel from different thread.

Geoff Darst - MSFT

Hi,

It sounds like your background thread got set to STA but you aren't pumping messages. The debugger monitors all STA threads and tries to periodically call into them to make sure that they aren't blocking. When more than a minute goes by, the MDA fires. The odd thing is that you are blocked. Off the top of my head, I can't think of why that would be. The STA proxy for Excel will enter a message loop after it posts the message containing the outgoing call. That should ensure the context switch. Then again, it might be that interop is expecting message pumping for some reason and is hanging you up. A full mixed mode stack should tell you what is going on, but probably the solution is to either set the ApartmentState property of your background thread to MTA prior to starting it or pump messages.

In general there is no problem with calling Office applications from multiple threads. However, there is also limited benefit because most Office applications are STA. This means that all calls into such objects will be serialized so you will never have the ability to concurrently access Excel. In addition, when you make cross-apartment calls, you must be able to handle the case where the call is rejected. The server is allowed to do this if the call comes in at an inopportune time (as defined by the server). This means that any call you make can throw a COM exception at any time. To prevent that from happening, you must implement the COM version of IMessageFilter (as opposed to the WinForms version) and call CoRegisterMessageFilter to register it. This interface has a RetryRejectedCall method that you will need to implement. Normally, you would wait some number of seconds and then display the OLEBusy dialog box.

Sincerely,

Geoff Darst

Microsoft VSTO Team