2

我设计了一个由 3 个独立的应用程序组成的系统:

  1. Web应用程序
  2. WCF 服务应用程序接收来自 Web 应用程序的请求,执行适当的操作并使用 SendKeys 类打印结果SendKeys.SendWait("^p");(这会发送一个 Ctrl + P 命令来打印屏幕上的内容)。
  3. 通过 Console.In 拦截打印机输出(通过 redmon 的虚拟打印机)的控制台应用程序(如此处所建议的

WCF 服务应用程序和 Web 应用程序可以轻松通信,但服务应用程序和控制台应用程序之间没有直接通信。控制台应用程序仅在有打印机作业且 WCF 应用程序不知道打印作业的结果时启动。

有没有办法让 WCF 服务应用程序接收来自打印作业的反馈(无论是否正常),因此它可以将适当的响应发送回 Web 应用程序,而无需Thread.Sleep()每秒执行一次,直到打印机应用程序完成打印并保存结果是文件还是数据库?

有没有办法我可以暂停 WCF 服务应用程序中的线程,并在打印过程完成后从打印机控制台应用程序恢复它(同时发送回信息)?

编辑:

我设法从 Richard Blewett 的建议中找到了解决方案。该解决方案将使 WCF 服务应用程序等到打印作业完成,但它会导致 WCF 应用程序被限制为一次只能制作一个打印作业。

我在 WCF 应用程序中创建了一个带有一些键的 EventWaitHandle,如下所示:

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

我可以像这样从控制台应用程序返回线程:

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

使用 Richard 的解决方案就不会出现这种情况,并且可以同时进行多个 WCF 服务调用。

4

1 回答 1

1

假设打印作业有一个唯一标识符,那么控制台应用程序可以调用 WCF 服务来说明打印作业是正常完成还是失败。

WCF 服务要么必须阻塞,直到完成调用进入(等待说 ManualResetEventSlim),要么您必须将服务编写为异步服务,以便在打印作业进行时请求线程可以返回到池中.

您需要打印作业的唯一标识符的原因是您必须在将唯一 ID 映射到事件的服务中的内存中保存一个数据结构,以便您可以在其作业完成时发出正确的等待请求

当 WCF 服务创建打印作业时,它会在 ConcurrentDictionary 中放入一个条目,例如将 printJobId 映射到无信号的 ManualResetEventSlim(每个打印作业一个)。然后它等待事件发出信号。

现在,当打印作业完成时,控制台应用程序依次调用 WCF 服务并传递其 printJobId。此操作对字典进行,抓取事件并发出信号。原来的呼叫现在醒来,知道打印作业已完成。

打印作业的状态也可以通过这个字典数据结构传递,所以你会有类似的东西

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

    public ManualResetEventSlim Event {get; private set;}

    public int Status{ get; set;}
}

并且字典会将 printJobId 映射到每个打印作业的其中一个。名为 operation 的控制台应用程序会将状态设置为打印作业的结果

于 2012-02-07T16:35:07.197 回答