Search code examples
c#sleepinfopathoffice-interop

Is there a better way than Thread.Sleep() to wait for example for PrintOut()?


I have made a small function which should print some InfoPath files. It is necessary to stop at some points the thread shortly that everything works fine. If I remove the Thread.Sleep(); for example the function close the application to fast. Now I would like to know, if there is a nicer way to solve that problem instead to stop the thread?

Here a piece of the function:

Application InfoPath = new Microsoft.Office.Interop.InfoPath.Application();
XDocument InfoPathXml = InfoPath.XDocuments.Open(XmlFile);
Thread.Sleep(Sleep);
InfoPathXml.PrintOut();
Thread.Sleep(Sleep);
InfoPath.Quit();
Thread.Sleep(Sleep);

The first sleep waits, until InfoPath has opened the document. The second one, waits for creating the print job. The last one, waits until the file is saved.

Edit Here is some new code... But sadly it doesn't work quite well... Only sometimes the event will be fired. Is there any other solution?

try
{
    Application InfoPath = new Microsoft.Office.Interop.InfoPath.Application();
    XDocument InfoPathXml = InfoPath.XDocuments.Open(XmlFile);
    InfoPathXml.OnContextChange += new _XDocumentEventSink2_OnContextChangeEventHandler(XmlFileLoaded);
    do
    {
        Thread.Sleep(0);
    } while (IsFileLocked(TempPath) == true);
    InfoPath.Quit();
}
catch (Exception exp)
{
    log.Write(exp.Message);
}

static private void XmlFileLoaded(DocEvent pEvent)
{
    pEvent.XDocument.PrintOut();
}

Edit2

Could anyone imagination why the event is not activated every time. If I start the program, the event is fired every 4th or 5th time.

There are two different cases which happen:

  1. The program opens the xml file with InfoPath, and nothing happens, it just waits. (Cause of the " IsFileLocked" function.) The event is not triggered.
  2. The event is triggered after the first file is open. After that, the event occurs at every file, everything works fine.

Could it be a problem with cashing the files, or something like that?

Edit3

Well, with the following event handling, I could solve the problem:

_Application3 InfoPathApplication = null;
ApplicationEvents InfoPathApplicationEvents = null;

InfoPathApplication = (Microsoft.Office.Interop.InfoPath._Application3)InfoPath;
InfoPathApplicationEvents = (Microsoft.Office.Interop.InfoPath.ApplicationEvents)InfoPathApplication.Events;
InfoPathApplicationEvents.XDocumentOpen += new _ApplicationEvents_XDocumentOpenEventHandler(XmlFileLoaded);


static private void XmlFileLoaded(_XDocument pEvent)
{
    pEvent.PrintOut();
    //pEvent.XDocument.PrintOut();
}

Solution

    1. Subscribe to event _ApplicationEvents_QuitEventHandler Quit
    2. Before exiting the app, wait for a semaphore.
    3. In the event handler (that is, when the InfoPath app exits), open up the semaphore.