Return 执行阻塞方法时的数据

Return data while executing blocking method

我想不出做这样的事情的方法:我有一个 C# 应用程序与另一个使用串行端口的设备连接,这个设备有时会产生中断,这会阻止它自身的执行,但是一旦它已修复该操作一直持续到完成。

以打印机为例,打印机开始打印 100 页的作业,但打印机内部有 70 张纸,因此打印机打印 70 页,然后通过 PC 警告用户放入更多纸张托盘。用户放入纸张后,打印继续,打印输出完成后,打印机将结果发送到PC。

就是这种情况,但发生的速度比打印机快。我怎样才能编写这样的代码?例如:

private void StartPrinting()
{    
    boolean bIsPrinted = SendPrinterDocument("p100.pdf");
}

private void ShowPaperOutError()
{
    MessageBox.Show("Paper is out. Please load some papers");
}

如果您只有这个 SendPrinterDocument() 方法,并且它会阻止应用程序的执行,就像它在 DLL 库上一样,您将如何触发 ShowPaperOutError() 消息?

仅供参考,我可以访问所有代码、PC 软件 (C#)、DLL (C#) 和设备 (C) 并可以编译它们。

您可以通过让 SendPrinterDocument return 对象来引发适当的事件,并可能公开适当的方法来执行您需要的操作。

我将使用(半)伪代码,因为我看不到您说您可以访问并可以更改的所有代码 - 我假设您将能够实现这个想法。

如果 SendPrinterDocument return 立即使用实现此示例接口的对象编辑:

public interface ISendPrinterDocumentResponse
{
    event EventHandler PrintingFinished;
    event EventHandler<PrintingInterruptedEventArgs> PrintingInterrupted;
    void Retry();
}

public class PrintingInterruptedEventArgs: EventArgs
{
     public string Reason { get;set; }
}

您可以像这样使用它:

var response = SendPrinterDocument("p100.pdf");
response.PrintingFinished = (s,ea) => MessageBox.Show("Finished");
response.PrintingInterrupted = (s,ea) => {
    MessageBox.Show("Printing stopped, hit ok to retry (reason:" + ea.Reason + ")");
    response.Retry();
};

根据评论编辑:

如果你的实际功能足够快以至于它在你实际分配事件处理程序之前完成,上面的想法很快就会崩溃,在这种情况下,你可能想要你的函数的第二个参数,它提供了一些 "callbacks" 当相关事件发生时被调用。您可以使用相同类型的设置:

public void SendPrinterDocument(string documentName, ISendPrinterEvents events);
{
     // when interrupted
     if(events.PrintingInterrupted != null)
     {
           events.PrintingInterrupted(this, new PrintingInterruptedEventArgs{Reason = "Out of paper"});
     }
}