views:

25

answers:

1

I've read a few other questions that seem similar but I'm still very confused, and none of the answers seem to be working for me so I decided to ask another question. Please bear with me, I'm not very well versed on threading and what not.

The application I am making is a 3rd party add-in for Revit Structure. The way they work is I hae a class library with a class that implements an interface, when that is called my application runs.

My tool is a Printing tool, it aims to automate printing to a PDF. I am trying to move my code over to using PdfCreator to print the PDFs (the way printing works in Revit is you set the printer and call the 'print' method in the API, so I can't do PDFs any way other than through a printer).

PDFCreator has a great COM interface that allows you to set its settings, as well as subscribing to an event which fires after every document is printed. I'm calling hte print method multiple times, so I want to wait until all are done, then do something in my code.

My logic goes like this:

  1. User Selects things to print
  2. Hits Print Button (on my WPF window)
  3. My Code then sets the PDF creator settings, and registers to listen to the event
  4. I call the Print() api method, which then takes some time to print each of the items
  5. I then want to be alerted when everything is done printing, and do some 'post processing' on the documents.
  6. Post processing involves renaming/moving PDFs around among other things

My problem is, that when I call the print method, my code doesn't wait for the PDFcreator events, it just continues through and exits, which means the post processing is never fired.

What I need to do is somehow wait for the event, without blocking.

After reading some other questions I've tried this:

  • AutoResetEvent, and use WaitOne until the event handler calls Set(). This just got stuck on WaitOne and never continued.
  • Application.DoEvents until a certain class variable has been set by the event handler..
  • I tried creating a new thread to sign up to the events but that didnt seem to help

how do I make the event fire on a new thread and then alert the current thread to keep going? Or how can I make the code wait for the event to fire ?

Let me know if you need any more info, happy to provide.

+1  A: 

Your problem is the following. That other library needs a running message loop to be able to fire the event. Specifically when a certain message arrives from the message loop that message is dispatched into the library and causes it to fire the event.

If you use some "wait" primitive in your calling code you block the message loop and thus the event is never fired. Your program should not block - it should continue running the message loop like every Windows GUI program does.

sharptooth
how do I continue running the message loop? do I need to show a form and wait for the event (I had some trouble with this, but may have given up too early)? My program calls the Print() API method, then I want to wait for sheets to print, and when they are done, do something else. Do I show a form while waiting, and then the event will fire?
RodH257
When trying to display a Gui using ShowDialog I get an AccessViolationException in regards to reading and writing protected memory
RodH257
You have to show some window and just keep it. Did you notice that if there's a button on the window and you click that button the event handler for the button is fired? That's done thanks to the message loop that is being run for you. You rely on it for the COm event handler as well. You just keep the window, the message loop is being run, the event fires and alters the state of your message handler.
sharptooth