none
Word VSTO - Application is busy exception!! RRS feed

  • Question

  • Hi I am using Open Office XML to generate a DOCX and after that using VSTO to convert that to DOC format. This solution was workingn fine for the past 5 months! Now suddently I am getting the following exception, when I restart the server it gets resolved! I understand this is because Word DLL is busy when the request is made, as soon as I got this exception I manually opened Word and saved a document - that worked fine! So why is my access through VSTO failing and throwing the following exception? How to resolve this without a system restart? Kindly help
    The message filter indicated that the application is busy.

    (Exception from HRESULT: 0x8001010A (RPC_E_SERVERCALL_RETRYLATER))


    Raja
    Thursday, April 16, 2009 12:32 AM

Answers

  • Hi Raja,

    Your code is failing because you are trying to make an object model call from a background thread and Word is not in a position where it can handle the call.  The issue is that Word is not thread-safe so it doesn't support concurrent access to its objects by multiple threads.  However, just because Word doesn't support concurrent access doesn't stop COM clients from trying to call in concurrently.  To solve this problem, COM has the notion of apartments.  Word resides in what is known as a Single Threaded Apartment (STA).  This apartment has thread affinity, so there is only one thread that ever executes code.  When a client from a different apartment makes a call, COM packages the call up into a message and posts it to Word's message queue.  When Word pumps the message, it dispatches it to a hidden window owned by COM and the call is unwrapped and executed.  However, before that happens, Word gets a chance to decide whether it wants to handle the call.  In cases where it is in a state where handling the call would not be a good idea (for example, when a modal dialog is being displayed) it will reject the call and the failed HRESULT gets converted to an RPC_E_SERVERCALL_RETRYLATER exception.  What this is telling you is that Word is busy, and you should try the call again later.

    The easiest solution is simply to not try to call into the object model on a background thread.  Since COM is serializing all cross-apartment calls anyway, acheiving a performance benefit from doing this is difficult.  Since Word won't handle the call until it gets around to pumping the message, your background thread is going to be blocked while it waits for the call to return.  Any other threads trying to call into Word will also be blocked.

    Otherwise, you have two choices.  The first choice is to simply handle the exception by retrying the call.  You would need some sort of looping construct to do this.  The problem is that you would need to do this for all object model calls being made on a background thread.  You could attempt to use interception to weave this code in via Aspect Oriented Programming, but that might be more trouble than it is worth.

    The other approach is to implement the COM (not Windows Forms) IMessageFilter interface which is the solution that COM provides for this problem.  IMessageFilter has a client method called RetryRejectedCall which will get called in the case of the server rejecting a call.  Typically you would provide an implementation that would silently retry the call for some period of time, after which it would call the COM function OLEUIBusy to display the standard "Ole busy" dialog to alert the user that they should check the server to see why it might be rejecting calls.  In addition to implementing IMessageFilter, you must register it by P/Invoking CoRegisterMessageFilter.  For details on implementing and registering IMessageFilter, see Andrew Whitechapel's blog here: http://blogs.msdn.com/andreww/archive/2008/11/19/implementing-imessagefilter-in-an-office-add-in.aspx

    Sincerely,

    Geoff Darst
    Microsoft VSTO Team
    Thursday, April 16, 2009 2:54 PM
    Answerer

All replies

  • Hi Raja

    I don't think we have enough information about your scenario

    1. Which version of VSTO is this? Is it a document-level or an application-level customization? (And Word 2007, I assume?)

    2. As VSTO runs in-process with the host application, I'm having difficulty understanding how a server is involved in your scenario. Could you please expand a bit more on the VSTO project and how a server comes into the picture?

    3. Please show us the code involved.

    Note: I get the impression that you aren't using VSTO, but "plain Interop". If so, then your question is off-topic here, as VSTO does run in-process. Consult the forum's Please Read First message for more information about what VSTO is, and for a list of venues for non-VSTO, Office-related questions.
    Cindy Meister, VSTO/Word MVP
    Thursday, April 16, 2009 7:24 AM
    Moderator
  • Hi Raja,

    Your code is failing because you are trying to make an object model call from a background thread and Word is not in a position where it can handle the call.  The issue is that Word is not thread-safe so it doesn't support concurrent access to its objects by multiple threads.  However, just because Word doesn't support concurrent access doesn't stop COM clients from trying to call in concurrently.  To solve this problem, COM has the notion of apartments.  Word resides in what is known as a Single Threaded Apartment (STA).  This apartment has thread affinity, so there is only one thread that ever executes code.  When a client from a different apartment makes a call, COM packages the call up into a message and posts it to Word's message queue.  When Word pumps the message, it dispatches it to a hidden window owned by COM and the call is unwrapped and executed.  However, before that happens, Word gets a chance to decide whether it wants to handle the call.  In cases where it is in a state where handling the call would not be a good idea (for example, when a modal dialog is being displayed) it will reject the call and the failed HRESULT gets converted to an RPC_E_SERVERCALL_RETRYLATER exception.  What this is telling you is that Word is busy, and you should try the call again later.

    The easiest solution is simply to not try to call into the object model on a background thread.  Since COM is serializing all cross-apartment calls anyway, acheiving a performance benefit from doing this is difficult.  Since Word won't handle the call until it gets around to pumping the message, your background thread is going to be blocked while it waits for the call to return.  Any other threads trying to call into Word will also be blocked.

    Otherwise, you have two choices.  The first choice is to simply handle the exception by retrying the call.  You would need some sort of looping construct to do this.  The problem is that you would need to do this for all object model calls being made on a background thread.  You could attempt to use interception to weave this code in via Aspect Oriented Programming, but that might be more trouble than it is worth.

    The other approach is to implement the COM (not Windows Forms) IMessageFilter interface which is the solution that COM provides for this problem.  IMessageFilter has a client method called RetryRejectedCall which will get called in the case of the server rejecting a call.  Typically you would provide an implementation that would silently retry the call for some period of time, after which it would call the COM function OLEUIBusy to display the standard "Ole busy" dialog to alert the user that they should check the server to see why it might be rejecting calls.  In addition to implementing IMessageFilter, you must register it by P/Invoking CoRegisterMessageFilter.  For details on implementing and registering IMessageFilter, see Andrew Whitechapel's blog here: http://blogs.msdn.com/andreww/archive/2008/11/19/implementing-imessagefilter-in-an-office-add-in.aspx

    Sincerely,

    Geoff Darst
    Microsoft VSTO Team
    Thursday, April 16, 2009 2:54 PM
    Answerer
  • Hi Cindy,

    I am using Microsoft Visual Studio 9.0\Visual Studio Tools for Office\PIA\Office12\Microsoft.Office.Interop.Word.dll. My application is hosted on IIS server, the application uses open office XML to generate a office 2007 DOCX because that is very quick in generating documents from the ground up, since the end users here are still using Office 2003 I am using Word VSTO to convert the DOCX to Doc, below is a snapshot of the VSTO piece of code that spins up WinWord.exe, opens Docx and saves it as Doc. This system is in use for almost 5 months now and this exception issue is coming up now! Any thoughts?

    m_App =

    new Microsoft.Office.Interop.Word.Application();

    generatedDocxDocument = m_App.Documents.Open(

    ref objGeneratedDocx, ref m_Missing, ref m_Missing, ref m_Missing, ref m_Missing,

     

    ref m_Missing, ref m_Missing, ref m_Missing, ref m_Missing, ref m_Missing, ref m_Missing,

     

    ref m_Missing, ref m_Missing, ref m_Missing, ref m_Missing, ref m_Missing);

    generatedDocxDocument.SaveAs(

    ref objGeneratedDoc, ref objDocFormat, ref m_Missing, ref m_Missing, ref m_Missing, ref m_Missing,

     

    ref m_Missing, ref m_Missing, ref m_Missing, ref m_Missing, ref m_Missing, ref m_Missing, ref m_Missing,

     

    ref m_Missing, ref m_Missing, ref m_Missing);


    Raja
    Thursday, April 16, 2009 4:49 PM
  • Raja,

    You are creating a new instance of Word, which means your calls are going cross-apartment.  You'll need to implement IMessageFilter as I suggested above.

    Sincerely,

    Geoff Darst
    Microsoft VSTO Team
    Thursday, April 16, 2009 8:43 PM
    Answerer
  • I am using Microsoft Visual Studio 9.0\Visual Studio Tools for Office\PIA\Office12\Microsoft.Office.Interop.Word.dll. My application is hosted on IIS server, the application uses open office XML to generate a office 2007 DOCX because that is very quick in generating documents from the ground up, since the end users here are still using Office 2003 I am using Word VSTO to convert the DOCX to Doc, below is a snapshot of the VSTO piece of code that spins up WinWord.exe, opens Docx and saves it as Doc. This system is in use for almost 5 months now and this exception issue is coming up now! Any thoughts?

    Hi Raja

    Geoff has kindly answered your question, please consult his information.

    For the future, please note that you are not using VSTO. VSTO is a special set of tools for the Office developer, primarily aimed at extending the UI for some Office applications. As such, VSTO solutions run in-process with the Office applications - there's never any need for VSTO to start up an instance of the application, nor run the application from another program. Such questions are best directed to one of the venues listed in this forum's Please Read First message.
    Cindy Meister, VSTO/Word MVP
    Friday, April 17, 2009 7:04 AM
    Moderator