我想不出一种方法可以做这样的事情:我有一个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),并可以编译它们。
答案 0 :(得分:4)
您可以通过让SendPrinterDocument
返回一个引发适当事件的对象来实现这一点,并且可能会使用适当的方法来执行您需要的操作。
我将使用(半)伪代码,因为我无法看到您说您可以访问并且可以更改的所有代码 - 我假设您将能够实现此想法。
如果SendPrinterDocument
立即返回实现此示例界面的对象:
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();
};
根据评论进行修改:
如果您的实际功能足够快以至于在实际分配事件处理程序之前完成,上面的想法会很快崩溃,在这种情况下,您可能需要为您的函数提供第二个参数,这提供了一些“回调”在相关事件发生时被调用。您可以使用相同类型的设置:
public void SendPrinterDocument(string documentName, ISendPrinterEvents events);
{
// when interrupted
if(events.PrintingInterrupted != null)
{
events.PrintingInterrupted(this, new PrintingInterruptedEventArgs{Reason = "Out of paper"});
}
}