How to asynchronously wait for response from an external application that intercepts printer output

StackOverflow https://stackoverflow.com/questions/9179658

  •  17-05-2021
  •  | 
  •  

Pregunta

I have designed a system that is made up of 3 separate applications:

  1. Web Application
  2. WCF Service application that receives requests from the web app, does the appropriate action and prints the result using the SendKeys class SendKeys.SendWait("^p"); (this send a Ctrl + P command that prints whats on the screen).
  3. Console application that intercepts printer output (virtual printer via redmon) via the Console.In (as suggested here

The WCF Service app and Web application can communicate easily, but there is no direct communication between the service app and console application. The console app only starts when there is a printer job and the WCF app doesn't know the result of the print job.

Is there a way to make the WCF Service app recieve feedback from the printed job (whether it was ok or not), so it can send appropriate response back to the web application, without doing Thread.Sleep() each second until the printer app finishes printing and saves the result in a file or database?

Is there a way i could pause the thread in the WCF service app, and resume it (whilst sending information back) from the printer console application when the printing process is done?

Edit:

I managed to find a solution from Richard Blewett's suggestions. The solution would make the WCF service app wait untill the print job is finnished, but it will cause the WCF app to be limited to only making one print job at a time.

I create an EventWaitHandle with some key in the WCF app like this:

EventWaitHandle ewh = new EventWaitHandle(false, EventResetMode.ManualReset, "unique-key");
WaitHandle.WaitAny(new WaitHandle[] { ewh });

And i can return to the thread from the Console app like this:

EventWaitHandle ewh = EventWaitHandle.OpenExisting("unique-key");
ewh.Set();

With Richard's solution this will not be the case, and multiple WCF service calls can be done simultaneously.

¿Fue útil?

Solución

Assuming there is a unique identifier for the print job then the console app could call the WCF service to say the print job is either completed OK or failed.

The WCF service would either have to block until the completion call came in (waiting on say a ManualResetEventSlim) or you would have to write the service as an async service so the request thread could be returned to the pool while the print job was in progress.

The reason you need a unique identifier for the print job is you will have to hold a data structure in memory in the service mapping unique id to event so you can signal the correct waiting request when its job is complete

When the WCF service creates a print job it puts an entry in, say, a ConcurrentDictionary mapping printJobId to a non signalled ManualResetEventSlim (one for each print job). It then waits for the event to signal.

Now when the print job completes, the console app in turn calls the WCF service passing its printJobId. This operation does to the dictionary, grabs the event and signals it. The original call now wakes up knowing that the print job is complete.

The status of the print job could also be passed via this dictionary data structure so you would have something like

class PrintJob
{
    public PrintJob()
    { 
        Event = new ManualResetEventSlim();
    }

    public ManualResetEventSlim Event {get; private set;}

    public int Status{ get; set;}
}

and the dictionary would map the printJobId to one of these for each print job. The console app called operation would set the status to the outcome of the print job

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top